Skip to content

SMAASH-project/Web

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

522 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Project smaash-web

This here repository contains the web app that goes along with the Unity game for our professional exam, written in Go with a TypeScript React frontend.

Getting Started

This section details how to get the source of project on your local machine to develop or test. For notes on how to deploy, see the deployment section of this document.

Prerequisites

You'll need the following tooling to be able to contribute:

  • Go tooling: Needed to run and compile the backend server. Find installation instructions for your OS here.
  • gcc: a C compiler needed to compile the CGO utility, which is used as a pseudo FFI between Go and C. Only needed if you decide to use a CGO based SQLite driver, which we no longer do, so this dependency is obsolete in the later releases. It stays in this document though so that testers choosing to switch database drivers don't accidentally miss this (like we did)
  • npm (Node Package Manager): Needed for running and building the website, which serves as the frontend of the application.

Optional tools

These tools aren't necessary, but very helpful if you want to contribute:

  • Just: a script runner (to replace Make), which we use to make running certain commands, like running, building, testing and seeding much more convinient. Installation instructions here.

Note

This documentation assumes that you have Just installed. If you choose not to use Just, you can run the commands defined in the justfile manually.

  • Go Air: a daemon that watches for changes and dynamically recompiles your Go projects while they're running, so for example, you don't have to restart the backend server when you make a change. Air is started by running just watch, which, if you don't have air installed, will ask you if you want to install it on your system, making installation a breeze.

Environment variables

The app depends on the following environment variables:

  • PORT (default: 8080)
  • DB_URL (default: test.db)
  • SEED_DATA_URI (default: ./internal/seeder/test_source)
  • SECRET_KEY (default: super_secret_key)
  • ALLOWED_ORIGINS (default: http://localhost:5173)
  • UPLOAD_DIR (default: ./uploads)

Setting up the project

1 - Clone the repo:

git clone https://github.com/SMAASH-project/Web.git

2 - Build project and seed database:

just all

This command will build the both the backend and the frontend, run all unit tests and seed the database with predefined data. For more on the project's seeder implementation, see the seeder section of this document.

3 - Run: Run the generated binary executable inside the build folder. Open your browser of choice, and navigate to http://localhost:8080/app and admire the beauty of our creation (xd).

Important

So far the output of the main executable file is without extension, meaning the built binary most likely won't run on Windows. Fixing this is on our todo list.


Development

This section details how to contribute to the project.

  • Dev servers:
    For development, make use of the dev servers that come with the toolchain we're using. From the root of the project, execute the following command to run the backend server:
just run

Then to start the Vite frontend server:

cd client && npm run dev
  • Project structure:
    The project contains the following folders:
  • build: contains the compiled binary of the app and the compiled assets it serves
  • client: contains the source code of the React TypeScript frontend project
  • cmd: contains the entry point(s) of programs included in the project (api and seeder in our case)
  • docs: contains documentation
  • internal contains the source code of the Go backend server

The documentation of the endpoints can be found in /docs/endpoins.md. For the schema of the DTOs, see inside the /internal/DTOs folder.

  • Dependency injection, layers:
    The project adheres to the following layering:
    database -> repository -> service (optional) -> controller -> server
    The workflow of creating endpoints should be as follows:
    1. Create a custom repository for your modes, or use the generic one
    2. If you need to handle buisness login, put it in a service which depends on your repo
    3. Define a controller that depends on your service, or if you didn't need one, your repo directly
    4. In the initialize function, found in /internal/initializer/initailzer.go, register your controller

Warning

NEVER put database queries or buisness logic in a controller. That's what repositories and services are for. Instead, make your controller depend on your services/repos by utilizing dependency injection

  • Defining repositories: The project is making use of the repository design pattern. A generic BaseRepository can be used in case you only need basic CRUD actions for a type in it's corresponging controller or service. E.g:
type RolesController struct {
	rolesBaseRepo repository.BaseRepository[models.Role]
}

In case you need custom or extended functionality, you can define a custom repo for a model in /internal/repository, by embedding the BaseRepository interface in your custom repo's interface, like so:

type UserRepository interface {
	BaseRepository[models.User]
	ReadByEmail(context.Context, string) (models.User, error)
}

type UserRepositoryActions struct {
	conn *gorm.DB
	BaseRepository[models.User]
}

For wrintig code, refer to the style guides and idioms of the languages we're using:

Debug & Admin panel

The app ships with a built-in debug/admin panel at /app/debug. Access is restricted to users with the admin role.

Tabs

Tab Description
System Browser info, display metrics, session, environment flags
Endpoints Interactive REST API explorer with quick-route presets and response inspector
Cache React Query cache browser — view, filter, invalidate, and remove cached queries
Game Data CRUD for characters, levels, and store items; user management (ban, promote, demote)
Database Generic data browser for all 11 API-exposed resources with row-level CRUD, schema view, session history, and a clearly marked danger zone
Visual Animation speed, layout borders, element inspector, FPS counter, scroll position overlay, CSS variable inspector
Emulation Viewport emulation presets, forced reduced motion, compact density, network delay/jitter simulation
Diagnostics A11y contrast ratios, render counters, React Query status, click-target and z-index inspectors

The debug settings (animation speed, viewport overrides, network simulation, etc.) are persisted to localStorage under the key debug-settings.


Database seeding

The project defines a database seeder, which can be used in the following way:

  1. Define some data you want to inject into the database in internal/seeder/source in a json format, e.g:
// internal/seeder/source/users.json
[
  {
    "Email": "[email protected]",
    "Password": "pass12345",
    "RoleID": 2
  },
  {
    "Email": "[email protected]",
    "Password": "admin1234",
    "RoleID": 1
  },
  {
    "Email": "[email protected]",
    "Password": "support1234",
    "RoleID": 3
  }
]
  1. Run just seed and watch the result in your terminal.

Note

The json source data has to follow the Go casing rules for public struct fields (Pascal case)

Swagger documentation

This project makes use of the swaggo/gin-swagger library, allowing declarative documentation comments to be used as OpenAPI definitions when automatically generating swagger docs. An example documentation for a controller:

// @description Creates a new role
// @tags roles
// @accept json
// @produce json
// @param role_create_dto body dtos.RoleCreateDTO true "dto for creating a new role"
// @success 201 {object} dtos.RoleReadDTO "returns newly created role"
// @failure 400 {object} dtos.ErrResp "request body in wrong format"
// @failure 401 {object} dtos.ErrResp "unauthorized"
// @failure 409 {object} dtos.ErrResp "unique key violation"
// @failure 500 {object} dtos.ErrResp "internal server error"
// @router /roles [post]
func (rc RolesController) Create(c *gin.Context) {...}

A detailed listing of available doc comments can be found here

When you're done doc-commenting your code run just swagger to generate the swagger.json and swagger.yml files. To view the generated web UI of the docs, navigate to /swagger/index.html

Version control and CI/CD

Here are the branches defined in this repository (and how to use them):

  • main: The main branch, you cannot push here. Main can only be populated via pull request from the test branch.
  • test: This branch is for testing the application before merging into main. You cannot push here, test can only be populated via pull requests from the backend and frontend branches.
  • backend: For developing the Go backend server. If you've worked on the server, push your commits here.
  • frontend: For developing the React SPA frontend. If you've worked on the website, push your commits here.

Flow of version control: Chart depicting the flow of version control

The repo utilizes a GitHub action for a CI pipeline. On every push or pull request, the project is built, the seeder is ran (on an in memory DB for testing purposes) and unit tests are executed. If any of these operations fail, a merge into main should'nt be made.

Deployment

To build the project, run just build-fullstack to build both the frontend and the backend. The result is the contents of the build folder, which contains the binary executalbe of the app, and in the client folder, the static assets it serves.

Note

Explicit cross compilation is not yet supported, it is on our agenda.

Deploy the contents of the build folder by any means you like

About

The web application to support the fantastic (xd) SMAASH game for school

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages