Skip to content

g0v/summit26-registration

Repository files navigation

g0v Summit 2026 報到 Registration Dashboard

This project is implemented with Leptos, a fullstack Rust framework. It's intended to be an application for g0v Summit 2026 registration desk. g0v Summit 2026 will issue VCs and verify attendee registration with moda's Ditigal Wallet, the registration dashboard is expected to be used only when manual registration is necessary. It syncs registration data between both digital wallet verification and manual registration (not yet implemented). For now it's demo only and is partially generated and modified with the help of Codex.

此專案會作為 g0v Summit 2026 報到資料後臺,g0v Summit 2026 將使用數位發展部的數位皮夾作為主要報到方式,此後臺僅在非數位皮夾到或需要確認報到狀況時由工作人員操作。其會同步數位皮夾報到與人工報到的資料(未實作),避免重複報到。目前處於 Demo 狀態,此專案由 Codex 協助產生及修改。

It shows a spreadsheet-like attendee table with name, ticket ID, ticket type, registration checkbox, and live registration status.

The app can run in two modes:

  • Frontend-only demo mode: uses built-in sample data in the browser. No database or backend is required.
  • Full mode: uses an Axum backend, Postgres, SQLx migrations, and a WebSocket channel to sync registration status across browser sessions.

Prerequisites

  • Rust 1.85.0 with the wasm32-unknown-unknown target
  • trunk
  • PostgreSQL, only for full mode
  • sqlx-cli, optional but useful for managing migrations manually

Example setup (rustup is recommended):

rustup toolchain install 1.85.0
rustup target add wasm32-unknown-unknown --toolchain 1.85.0
cargo install trunk
cargo install sqlx-cli --no-default-features --features rustls,postgres

For Nix User Only

If you want to use the included flake file, copy flake.nix.example to flake.nix, and enter the dev shell instead:

nix develop

The flake shell provides stable Rust 1.85.0, rust-analyzer, Trunk, cargo-leptos, PostgreSQL client tools, and sqlx-cli.

Configuration

Copy the example config before running the backend:

cp config.example.toml config.toml

config.toml has two sections:

[server]
host = "127.0.0.1"
port = 3000
dist_dir = "dist"

[database]
url = "postgres://conference_user:conference_password@localhost:5432/conference_registration"
max_connections = 5
  • server.host: address the Axum backend binds to.
  • server.port: backend HTTP/WebSocket port.
  • server.dist_dir: directory containing the Trunk-built frontend.
  • database.url: Postgres connection string.
  • database.max_connections: SQLx pool size.

The backend uses config.toml automatically when it exists. You can override the path with:

APP_CONFIG=/path/to/config.toml cargo run --features server --bin server

Mock Data And Migration

The database schema and seed data live in:

migrations/20260430000100_create_attendees.sql

The migration creates an attendees table:

The insert uses ON CONFLICT (ticket_id) DO NOTHING, so rerunning migrations does not overwrite existing attendee rows.

Run Without Postgres

Use this mode to see the UI without a backend or database on port 8080:

trunk serve --address 127.0.0.1 --port 8080

Open:

http://127.0.0.1:8080/

Expected result:

  • The page loads with built-in sample attendees.
  • The top-right status shows sample/demo state instead of Live Data.
  • Checking rows changes the browser state only.
  • Refreshing resets to sample data because no backend is running.

Run With Postgres

Create a Postgres database and user that match config.toml, or update database.url to match your local setup.

Build the frontend:

trunk build

Run the backend:

cargo run --features server --bin server

Open:

http://127.0.0.1:3000/

Expected result:

  • The backend connects to Postgres.
  • SQLx runs the migration automatically.
  • The page loads attendee rows from the attendees table.
  • The top-right status changes to Live Data once the initial database fetch succeeds and the WebSocket opens.
  • Checking or unchecking a row updates Postgres.
  • Other open browser sessions receive the registration update over WebSocket.

For development, you can also run Trunk and the backend separately:

make serve
make run-server

Open the Trunk URL. make serve reads server.bind_host and server.port from config.toml and points frontend API/WebSocket traffic at that backend. Plain trunk serve also does this when auth.development = true and frontend.backend_public_url is empty.

Deploy Behind Nginx

For a public path such as:

https://38552170.wallet.gov.tw/registration/

do not proxy public traffic to trunk serve. trunk serve is a development server and injects /.well-known/trunk/ws live-reload WebSocket code. Build static files instead:

make deploy-build

Serve the generated dist/ directory at /registration/.

Set the public backend URL in config.toml before building the frontend:

[server]
bind_host = "127.0.0.1"
port = 3000
dist_dir = "dist"

[auth]
username = "admin"
password = "change-me"
development = false
require_https = true

[frontend]
backend_public_url = "/ap"

make deploy-build reads frontend.backend_public_url through the normal build configuration path; edit config.toml rather than the Makefile.

Then configure nginx to proxy /ap/ to the backend and strip the /ap prefix before forwarding. WebSocket upgrade headers are required for /ap/ws/registrations. When auth.require_https = true, nginx must forward the original scheme:

proxy_set_header X-Forwarded-Proto $scheme;

For local development, set:

[auth]
development = true
require_https = false

Basic auth is still required in development. The development flag only disables HTTPS enforcement. The server also permits non-HTTPS requests to local hosts (localhost, 127.0.0.1, and [::1]) so make serve plus make run-server can work without TLS.

The Rust server uses Basic auth for the frontend it serves, attendee APIs, and the registration WebSocket. The verifier deeplink endpoints and verifier callback remain unauthenticated so external verifier flows can call them. If you serve dist/ directly from nginx, also configure Basic auth in nginx for /registration/; otherwise the static frontend can be loaded, but attendee API/WebSocket access will still be blocked by the Rust server.

Basic auth is simple but not ideal long-term: prefer nginx/OIDC, a session cookie login flow with CSRF protection, or a reverse-proxy access product for production.

The default Trunk.toml builds assets for /registration/, so plain trunk build also works when config.toml has:

[frontend]
backend_public_url = "/ap"

Useful local commands:

make serve
make run-server
make check
make check-server
make check-wasm

Notes

This is not production ready. Data syncing with verification server, authentication, authorization, logs, attendee search etc. are not yet implemented.

與數位皮夾驗證 API 溝通、權限控管及眾多 production 功能還未實作。

About

g0v Summit 2026 與數位皮夾同步/手動報到平臺

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors