Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
# Nuxt SEO
#NUXT_SITE_ENV="staging"
NUXT_SITE_URL="https://hackathon.cslabs.be"
NUXT_SITE_NAME="Le Hackathon du CSLabs"
NUXT_SITE_DESCRIPTION="Le Hackathon du CSLabs : 48h pour imaginer, prototyper et présenter un projet tech en équipe."

NUXT_OG_IMAGE_SECRET=""

# Cloudflare Turnstile
NUXT_TURNSTILE_SITE_KEY=""
NUXT_TURNSTILE_SECRET_KEY=""

NUXT_SMTP_HOST=""
NUXT_SMTP_PORT="8465"
NUXT_SMTP_USER=""
NUXT_SMTP_PASSWORD=""
# Email
NUXT_SMTP_HOST="localhost"
NUXT_SMTP_PORT="1025"
NUXT_SMTP_USER="test"
NUXT_SMTP_PASSWORD="test"
NUXT_SMTP_REPLY_TO="[email protected]"

NUXT_OG_IMAGE_SECRET=""

# Supabase client
SUPABASE_URL="https://supabase-hackathon.cslabs.be"
SUPABASE_KEY=""
SUPABASE_SECRET_KEY=""
SUPABASE_KEY="sb_publishable_XXX"
SUPABASE_SECRET_KEY="sb_secret_XXX"

# Database
DATABASE_URL="postgresql://postgres:password@localhost:5432/postgres"

CLAMAV_HOST=""
CLAMAV_PORT=""
# ClamAV
CLAMAV_HOST="localhost"
CLAMAV_PORT="3310"
11 changes: 10 additions & 1 deletion .github/actions/setup-node-pnpm/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ inputs:
pnpm-version:
description: 'The pnpm version to setup'
required: false
working-directory:
description: 'The directory where pnpm install should run'
required: false
default: '.'
cache-dependency-path:
description: 'The pnpm lockfile path used for cache invalidation'
required: false
default: 'pnpm-lock.yaml'
database-url:
description: 'The database URL to use during dependency installation'
required: false
Expand All @@ -25,14 +33,14 @@ runs:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
cache: true
version: ${{ inputs.pnpm-version }}

- name: Setup Node.js cache
uses: actions/setup-node@v6
with:
node-version: ${{ inputs.node-version }}
cache: pnpm
cache-dependency-path: ${{ inputs.cache-dependency-path }}

- name: Show versions
shell: bash
Expand All @@ -42,6 +50,7 @@ runs:

- name: Install dependencies
shell: bash
working-directory: ${{ inputs.working-directory }}
run: pnpm install --frozen-lockfile
env:
DATABASE_URL: ${{ inputs.database-url }}
Expand Down
64 changes: 64 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
name: Build and deploy documentation

on:
push:
branches: [ main, deploy ]
paths: [ "docs/**" ]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

env:
NODE_VERSION: 22

jobs:
build:
runs-on: ubuntu-latest

defaults:
run:
working-directory: ./docs

steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0

- name: Setup Node + pnpm and install dependencies
uses: ./.github/actions/setup-node-pnpm
with:
node-version: ${{ env.NODE_VERSION }}
cache-dependency-path: docs/pnpm-lock.yaml
working-directory: ./docs

- name: Setup Pages
uses: actions/configure-pages@v5

- name: Build documentation
run: pnpm run build

- name: Upload GitHub Pages artifact
uses: actions/upload-pages-artifact@v4
with:
path: docs/.vitepress/dist

deploy:
name: Deploy
needs: build
runs-on: ubuntu-latest

environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}

steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
2 changes: 2 additions & 0 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vitepress/dist
.vitepress/cache
89 changes: 89 additions & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { defineConfig } from "vitepress";

// https://vitepress.dev/reference/site-config
export default defineConfig({
title: "Hackathon Docs",
description: "Developer documentation for the Hackathon platform",
lang: "en-BE",
lastUpdated: true,
base: "/",
sitemap: {
hostname: "https://docs.hackathon.cslabs.be",
},
themeConfig: {
// https://vitepress.dev/reference/default-theme-config
search: {
provider: "local",
},
nav: [
{text: "Onboarding", link: "/onboarding/"},
{text: "Architecture", link: "/architecture/"},
{text: "Frontend", link: "/frontend/"},
{text: "Backend", link: "/backend/"},
{text: "Operations", link: "/operations/"},
{text: "ADRs", link: "/adrs/"},
],
sidebar: {
"/onboarding/": [
{
text: "Onboarding",
items: [
{text: "Overview", link: "/onboarding/"},
{text: "Local Setup", link: "/onboarding/local-setup"},
{text: "Environment", link: "/onboarding/environment"},
],
},
],
"/architecture/": [
{
text: "Architecture",
items: [
{text: "Overview", link: "/architecture/"},
{text: "Auth & RBAC", link: "/architecture/auth-rbac"},
{text: "Data Model", link: "/architecture/data-model"},
],
},
],
"/frontend/": [
{
text: "Frontend",
items: [
{text: "Overview", link: "/frontend/"},
],
},
],
"/backend/": [
{
text: "Backend",
items: [
{text: "Overview", link: "/backend/"},
{text: "API", link: "/backend/api"},
],
},
],
"/operations/": [
{
text: "Operations",
items: [
{text: "Overview", link: "/operations/"},
],
},
],
"/adrs/": [
{
text: "ADRs",
items: [
{text: "Overview", link: "/adrs/"},
{text: "Nuxt", link: "/adrs/nuxt"},
{text: "Prisma", link: "/adrs/prisma"},
{text: "Supabase", link: "/adrs/supabase"},
],
},
],
},
socialLinks: [
{icon: "github", link: "https://github.com/CSLabsNamur/hackathon-website/"},
],
outline: "deep",
},
});
28 changes: 28 additions & 0 deletions docs/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License

Copyright (c) 2025, CSLabs

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 changes: 35 additions & 0 deletions docs/adrs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: ADRs
description: Architecture Decision Records for the project.
---

# ADRs

ADR means `Architecture Decision Record`.

An ADR is a short document describing:

- the context of a technical choice;
- the decision that was made;
- the main alternatives that were considered;
- the consequences of the decision.

The goal is give the next maintainer enough context to understand why the code looks the way it does.

## When to add one

Add an ADR when a decision is likely to matter months later, for example:

- changing the deployment model;
- choosing a major library (e.g. for test suites);
- changing the UI library;
- changing how authorization or data storage works, etc.

Do not create ADRs for every small refactor. The goal is to capture decisions that are likely to be relevant in the
future, not to document every change.

## Existing ADRs

- [Nuxt](/adrs/nuxt)
- [Prisma](/adrs/prisma)
- [Supabase](/adrs/supabase)
47 changes: 47 additions & 0 deletions docs/adrs/nuxt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: ADR - Nuxt
description: Why the project is built as a single Nuxt application.
---

# Nuxt

## Context

The project needs to serve a public website, a participant dashboard, an admin dashboard, and a server API.
It needs good SEO support, so SSR is a must.
Those surfaces share the same event data, the same authentication model, and the same deployment lifecycle.

## Decision

Use a single Nuxt application for the public frontend, the dashboards, and the Nitro API.

## Why

- Nuxt gives us a unified framework for both frontend and backend code, which fits the project well.
- The public pages and the dashboards can share components, styles, and data fetching logic.
- Authentication and permission logic only need to be implemented once.
- Deployment is simpler because the project remains a single deployable unit.
- Nuxt gives us SSR support out of the box.
- With Nuxt modules, we can easily integrate with SEO tools, analytics, and other services as needed.
- The opinionated structure of Nuxt helps keep the code organized, and future maintainers can quickly understand where
to find different types of code (e.g. pages, components, server routes, etc.).
- The project is not large enough to justify the overhead of maintaining separate repositories or a custom API server.

## Alternatives considered

### Separate frontend and backend repositories

This was the case in the old website, and it caused a lot of overhead in terms of code duplication and deployment
complexity. NestJS is a great framework, very scalable and great to work with, but it's overkill for this platform.

### Use a different full-stack framework (e.g. Next.js)

Honnestly, it was solely a personnal choice. Next.js is a great framework, but I find Vue to be easier to work with, and
easier to onboard new developers on. I also just don't want to deal with useEffect.

## Downsides

- The repository structure is broader than a simple Nuxt marketing site, so documentation matters more.
- Developers need to understand both client and server conventions, even if they mostly work on one side.
- New maintainers might need to learn Vue and Nuxt a bit if they are not already familiar with it, though it should be
straightforward to pick up.
Loading
Loading