The first principle, from which all others are derived. gractwo.org
readme.md

gractwo.org/arche #

This is a monolith encompassing atproto login, atproto handle provisioning, serving a website and running a minor discord server bot which manages things like cyclical events. It uses SQLite as its database.

Deployment #

Currently deployed via NixOS.

Deploying requires HTTPS: release builds use Secure cookies, and the AT Protocol OAuth client metadata is hardcoded to https://gractwo.pl (dev builds use http://localhost:2020). A release build served from any other domain will send users to an OAuth callback that doesn't belong to it.

The binary listens on two ports, both hardcoded: 2020 for the site and API, and 2021 for the atproto handle provider. The handle provider answers /.well-known/atproto-did based on the request's Host header, so it needs its own reverse proxy entry - e.g. handle="*.gractwo.pl" in Caddy, or a server_name block in nginx - pointing at 2021. Handles claimed through the panel are validated to end in .gractwo.pl and expect corresponding wildcard DNS.

NixOS (w/ build) #

For NixOS, the flake exposes nixosModules.default. It packages the server and runs it with default DB_PATH, CFG_PATH and BLOB_STORE_PATH variables pointed at files under /var/lib/arche, its StateDirectory.

It does not supply DISCORD_BOT_TOKEN or DISCORD_SERVER_ID, so those need to be securely injected by your system configuration - for example via sops templates and systemd.services.arche.serviceConfig.EnvironmentFile. Otherwise parts of functionality of both the website and the bot will be lost.

The flake provides tailwindcss_4 and sets EXPLICIT_TAILWIND_BINARY, so css can compile sandboxed build environment.

Development #

No database server is required - the app uses SQLite. A data.db file (plus -wal and -shm) is created in the working directory on first run, and migrations in src/db/migrations are applied automatically at startup.

The Discord credentials are read from the environment and are able to be loaded from a .env file. Example:

DISCORD_BOT_TOKEN=your-bot-token
DISCORD_SERVER_ID=447075692664979466

Running the app is done via cargo (cargo run), which serves the site at localhost:2020. Without a valid bot token the server still boots, but member counts and the automation services stay silent.

Cargo will download a tailwindcss binary to compile styles on the first build. If you'd rather it not do that, please provide a EXPLICIT_TAILWIND_BINARY=./path/to/tailwind env var.

Logging is controlled by RUST_LOG and defaults to info,serenity=warn. An unreadable or missing .env is only a warning.

Branding assets #

assets/ is a git subtree of gractwo.org/assets, which only contains SVGs. src/branding.rs rasterises logo variants on first use at multiple sizes and caches it in a OnceLock; that is what feeds the favicons and the seasonal Discord guild icon.

Use git subtree pull --prefix=assets https://tangled.org/gractwo.org/assets master --squash to update.

Logging in locally #

The panel is gated by an AT Protocol allowlist, and there is no default account. For development, use the "Login deweloperski" (developer login) button, which appears on /login in debug builds only. It creates a fake did:web:example.org session and refuses to run in release builds, so there's no way to sneak into a production instance with it. Everyone on the allowlist currently gets the whole panel; src/permissions.rs sketches a finer permission model, but nothing enforces it yet.

What's in here #

  • / - landing page with the member counter, community age and association age, all computed live.
  • /struktury - the association's org chart, currently hardcoded in src/website/pages/struktury.rs.
  • /dane-prawne - registry data (KRS, NIP, REGON) and the bank account.
  • /login, /panel-sterowania - ATProto OAuth login and the control panel: allowlist management, session revocation, audit log and atproto handle claims.
  • /api/* - live, discord-member-count, days-community and amu-uptime, the last one being a keyword check against amu.edu.pl with a 30 second cache.
  • Short redirects for the community's links: /discord, /git, /github, /youtube, /bsky, plus /index* pointing home.

assets/ holds the Gractwo logos; web/ holds the tailwind input and icons. The bot swaps in seasonal variants (pride, national colours, Star Wars day) by renaming the guild and uploading one of these on the relevant dates.