Skip to content

Commit 277a338

Browse files
authored
3.1.0
2 parents 0aaf53e + 0be7264 commit 277a338

126 files changed

Lines changed: 2791 additions & 1441 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.dockerignore

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
**/node_modules
22
.pnpm-store
33
.git
4+
5+
# gitignored / secrets - must never enter the build context
6+
config
7+
.env
8+
.secrets
9+
release.json
10+
11+
# not needed to build, keeps context small and cache stable
12+
.github
13+
.vscode
14+
docs
15+
*.md
16+
event.json
17+
compose.yml
18+
.prettierignore
19+
.prettierrc.json
20+
oxlint.config.ts

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ jobs:
77
checks:
88
name: Lint & Format
99
runs-on: ubuntu-latest
10-
if: github.actor != 'dependabot[bot]'
10+
if: github.actor != 'dependabot[bot]' || contains(github.event.pull_request.labels.*.name, 'javascript')
1111
steps:
1212
- name: Checkout code
13-
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
13+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
1414

1515
- name: Setup pnpm
16-
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6.0.8
16+
uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9
1717
with:
1818
version: 11
1919

.github/workflows/docker-release.yml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
packages: write
1717
steps:
1818
- name: Checkout code
19-
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
19+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
2020

2121
- name: Extract version and tags
2222
run: |
@@ -35,6 +35,9 @@ jobs:
3535
- name: Extract repository name (lowercase)
3636
run: echo "REPO_NAME=$(basename ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
3737

38+
- name: Extract full repository path (lowercase, for GHCR)
39+
run: echo "GHCR_REPO=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
40+
3841
- name: Set up QEMU
3942
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
4043
with:
@@ -54,6 +57,14 @@ jobs:
5457
username: ${{ secrets.DOCKERHUB_USERNAME }}
5558
password: ${{ secrets.DOCKERHUB_TOKEN }}
5659

60+
- name: Log in to GitHub Container Registry
61+
if: ${{ !env.ACT }}
62+
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
63+
with:
64+
registry: ghcr.io
65+
username: ${{ github.actor }}
66+
password: ${{ secrets.GITHUB_TOKEN }}
67+
5768
- name: Build and push
5869
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
5970
with:
@@ -64,6 +75,9 @@ jobs:
6475
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ env.VERSION }}
6576
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:${{ env.MAJOR_MINOR }}
6677
${{ secrets.DOCKERHUB_USERNAME }}/${{ env.REPO_NAME }}:latest
78+
ghcr.io/${{ env.GHCR_REPO }}:${{ env.VERSION }}
79+
ghcr.io/${{ env.GHCR_REPO }}:${{ env.MAJOR_MINOR }}
80+
ghcr.io/${{ env.GHCR_REPO }}:latest
6781
cache-from: type=gha
6882
cache-to: type=gha,mode=max
6983
build-args: |

.prettierignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/config
2+
3+
**/node_modules
4+
**/dist
5+
**/route.gen.ts
6+
pnpm-lock.yaml
7+

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# ---- BASE ----
2-
FROM node:25-alpine AS base
2+
FROM node:26-alpine AS base
33
RUN npm install -g pnpm
44

55
# ---- BUILDER ----
@@ -18,7 +18,7 @@ COPY . .
1818
RUN pnpm build
1919

2020
# ---- RUNNER ----
21-
FROM alpine:3.23.4 AS runner
21+
FROM alpine:3.24.1 AS runner
2222

2323
RUN apk add --no-cache nginx nodejs supervisor
2424

README.md

Lines changed: 22 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Choose one of the following deployment methods:
2525

2626
### Without Docker
2727

28-
- Node.js : version 22 or higher
28+
- Node.js : version 24 or higher
2929
- PNPM : version 10.16 or higher (learn more [here](https://pnpm.io/))
3030

3131
### With Docker
@@ -55,6 +55,15 @@ docker run -d \
5555
ralex91/razzia:latest
5656
```
5757

58+
The image is also published on the GitHub Container Registry, if you prefer using it instead of Docker Hub:
59+
60+
```bash
61+
docker run -d \
62+
-p 3000:3000 \
63+
-v ./config:/app/config \
64+
ghcr.io/ralex91/razzia:latest
65+
```
66+
5867
**Configuration Volume:**
5968
The `-v ./config:/app/config` option mounts a local `config` folder to persist your game settings and quizzes. This allows you to:
6069

@@ -85,87 +94,34 @@ pnpm install
8594

8695
```bash
8796
# Development mode
88-
pnpm run dev
97+
pnpm dev
8998

9099
# Production mode
91-
pnpm run build
100+
pnpm build
92101
pnpm start
93102
```
94103

95104
## ⚙️ Configuration
96105

97-
The configuration is split into two main parts:
98-
99-
### 1. Game Configuration (`config/game.json`)
100-
101-
Main game settings:
106+
**⚠️ Required:** set a manager password in `config/game.json` before going live.
102107

103108
```json
104109
{
105110
"managerPassword": "PASSWORD"
106111
}
107112
```
108113

109-
Options:
110-
111-
- `managerPassword`: The master password for accessing the manager interface. **Must be changed from the default `"PASSWORD"` value**, otherwise manager access is blocked.
114+
`managerPassword` **must be changed** from the default `"PASSWORD"` value, otherwise manager access is blocked.
112115

113-
### 2. Quiz Configuration (`config/quizz/*.json`)
114-
115-
Quizzes can be created in two ways:
116-
117-
- **Via the Quiz Editor** — use the built-in editor available in the manager dashboard (recommended)
118-
- **Via JSON files** — manually create files in the `config/quizz/` directory
119-
120-
You can have multiple quiz files and select which one to use when starting a game.
121-
122-
Example quiz configuration (`config/quizz/example.json`):
123-
124-
```json
125-
{
126-
"subject": "Example Quiz",
127-
"questions": [
128-
{
129-
"question": "What is the correct answer?",
130-
"answers": ["No", "Yes", "No", "No"],
131-
"solutions": [1],
132-
"cooldown": 5,
133-
"time": 15
134-
},
135-
{
136-
"question": "Which of these are primary colors?",
137-
"answers": ["Red", "Green", "Blue", "Yellow"],
138-
"solutions": [0, 2, 3],
139-
"cooldown": 5,
140-
"time": 20
141-
},
142-
{
143-
"question": "What is the correct answer with an image?",
144-
"answers": ["No", "Yes", "No", "No"],
145-
"media": {
146-
"type": "image",
147-
"url": "https://placehold.co/600x400.png"
148-
},
149-
"solutions": [1],
150-
"cooldown": 5,
151-
"time": 20
152-
}
153-
]
154-
}
155-
```
116+
## 📚 Documentation
156117

157-
Quiz Options:
118+
- [Configuration](docs/configuration.md): manager password, via the `config` folder.
119+
- [Quiz](docs/quiz.md): creating and structuring quizzes.
120+
- [Branding](docs/branding.md): optional custom theming.
121+
- [Reverse Proxy](docs/reverse-proxy.md): running behind Traefik, Nginx, Caddy, or another reverse proxy.
122+
- [WebSocket Protocol](docs/websocket-protocol.md): build a custom client (e.g. an ESP32 physical buzzer).
158123

159-
- `subject`: Title/topic of the quiz
160-
- `questions`: Array of question objects containing:
161-
- `question`: The question text
162-
- `answers`: Array of possible answers (2-4 options)
163-
- `media`: Optional media object displayed with the question:
164-
- `type`: `"image"`, `"video"`, or `"audio"`
165-
- `url`: URL of the media
166-
- `solutions`: Array of correct answer indices (0-based). Use multiple indices for multi-answer questions
167-
- `cooldown`: Time in seconds before answers are revealed (3-15)
168-
- `time`: Time in seconds allowed to answer (5-120)
124+
Full index in [docs/](docs/README.md).
169125

170126
## 🎮 How to Play
171127

@@ -183,4 +139,4 @@ For bug reports or feature requests, please [create an issue](https://github.com
183139

184140
## ⭐ Star History
185141

186-
[![Star History Chart](https://api.star-history.com/svg?repos=Ralex91/Razzia&type=date&legend=bottom-right)](https://www.star-history.com/#Ralex91/Razzia&type=date&legend=bottom-right)
142+
[![Star History Chart](https://api.star-history.com/svg?repos=Ralex91/Razzia&type=date&logscale=&legend=bottom-right)](https://www.star-history.com/#Ralex91/Razzia&type=date&logscale=&legend=bottom-right)

docker/nginx.conf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ server {
88
try_files $uri $uri/ /index.html;
99
}
1010

11+
location /branding/ {
12+
alias /app/config/branding/;
13+
}
14+
1115
location /ws {
1216
proxy_pass http://127.0.0.1:3001;
1317
proxy_http_version 1.1;

docs/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# 📚 Documentation
2+
3+
This folder covers the basic setup (config, quizzes, branding) as well as more advanced usage, like running behind a reverse proxy or building your own client.
4+
5+
- [Configuration](configuration.md): manager password, via the `config` folder.
6+
- [Quiz](quiz.md): creating and structuring quizzes via `config/quizz/*.json`.
7+
- [Branding](branding.md): optional custom theming via `config/branding/`.
8+
- [Reverse Proxy](reverse-proxy.md): running Razzia behind Traefik, Nginx, Caddy, or another reverse proxy.
9+
- [WebSocket Protocol](websocket-protocol.md): the player-facing event protocol, for building custom clients (e.g. a physical buzzer).
10+
11+
Back to the [main README](../README.md).

docs/branding.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Custom Branding
2+
3+
Optional, lives in `config/branding/` (alongside `config/game.json`, see [Configuration](configuration.md)).
4+
5+
You can fully rebrand the app **without touching the code** by dropping files into a `config/branding/` folder. If it is absent, the default look is used.
6+
7+
Create `config/branding/theme.json`:
8+
9+
```json
10+
{
11+
"appName": "My Quiz",
12+
"colors": { "primary": "#ff9900", "secondary": "#1a140b" },
13+
"answerColors": ["#e69f00", "#56b4e9", "#3dbfa0", "#cc79a7"],
14+
"font": {
15+
"family": "Rubik",
16+
"url": "https://fonts.googleapis.com/css2?family=Rubik:wght@300..900&display=swap"
17+
},
18+
"logo": "/branding/logo.svg",
19+
"favicon": "/branding/favicon.svg",
20+
"background": "/branding/background.png"
21+
}
22+
```
23+
24+
All fields are optional: anything you omit keeps its default value.
25+
26+
- `appName`: app name + browser tab title
27+
- `colors`: CSS color tokens (at least `primary` and `secondary`)
28+
- `answerColors`: up to 4 answer-button colors
29+
- `font`: a font family + an optional stylesheet URL (e.g. Google Fonts)
30+
- `logo` / `favicon` / `background`: drop the files in `config/branding/` and reference them here

docs/configuration.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Configuration
2+
3+
The configuration lives in the `config` folder (mounted as a Docker volume, or `../../config` relative to the packages when running without Docker).
4+
5+
## Game Configuration (`config/game.json`)
6+
7+
Main game settings:
8+
9+
```json
10+
{
11+
"managerPassword": "PASSWORD"
12+
}
13+
```
14+
15+
Options:
16+
17+
- `managerPassword`: The master password for accessing the manager interface. **Must be changed from the default `"PASSWORD"` value**, otherwise manager access is blocked.
18+
19+
See also: [Quiz Configuration](quiz.md) and [Custom Branding](branding.md), also stored in the `config` folder.

0 commit comments

Comments
 (0)