2026-04-09

Shipped

Discord OAuth (PRs #86, #87, #88)

  • Password change form in settings (Better Auth changePassword)
  • Discord OAuth link/unlink from dashboard settings
  • “Log in with Discord” on login page
  • Discord icon with brand colors (#5865F2 Blurple)
  • Orphaned session handling — if someone logs in with Discord but has no guild member, sign out and show error
  • Biome lint cleanup — zero warnings now

Authentik SSO (PR #89)

  • Deployed Authentik at auth.dungeon.club on Cosmos (Proxmox LXC)
  • Discord as social login source (Marty prod app)
  • HedgeDoc (write.dungeon.club) live with OIDC via Authentik
  • Guild Member group gates app access — only guild members can log in
  • syncMemberToAuthentik() runs on signup, creates Authentik user + adds to group
  • Backfilled all 7 existing members via script
  • Flow: Discord → Authentik → HedgeDoc, gated by guild membership

HedgeDoc

  • Moved from Tailnet-only (hedgedoc.kuroda.cloud) to public (write.dungeon.club)
  • Switched to host network mode (both HedgeDoc + MariaDB)
  • Disabled email registration, anonymous access off
  • OAuth2 via Authentik for login
  • Created “The Guild Wall” — shared doc for members

Decisions

Guild activity feed privacy

  • Show by default: level ups, GM bonus XP awards (no real-world info)
  • Opt-in only (future): check-ins, events (location/schedule = stalking risk)
  • Never show: purchases, redemptions, tier changes (personal/financial)
  • No timestamps on kiosk — don’t reveal who’s in the shop right now
  • Documented in docs/plans/guild-activity-feed.md

Ebook access model

  • DRM-free ebooks are “personal use only” — can’t host purchased ebooks for other members
  • Purchase fulfillment (you bought it, here’s your PDF) = email a link, no Kavita needed, no signup needed
  • Guild library = free reference shelf only (SRDs, basic rules, quickstarts, CC-licensed)
  • Not a tier-gated perk — just a utility (“playing Mork Borg tonight? Here’s the basic rules”)
  • Carrie + publisher conversations needed before any broader library
  • Documented in docs/plans/ebook-access-model.md

Architecture: Guild → Authentik (not via Discord/Marty)

  • Guild pushes membership directly to Authentik — no Discord middleman
  • Marty stays a Discord bot, not in the auth chain
  • Discord role sync (Marty) is optional/cosmetic, Phase 3
  • Documented in updated docs/plans/discord-integration.md

Infrastructure

  • Beelink N95 maxed out at 8GB RAM running Authentik + everything else
  • Bumped Cosmos LXC to 3GB RAM, 2GB swap (took 1GB from Home Assistant)
  • Ordering 16GB DDR4 SO-DIMM (~$120, DDR4 shortage from AI demand)
  • Authentik needs: PostgreSQL 16, Redis 8, server + worker containers
  • All containers on host network mode for Cloudflare tunnel access

Guild user feedback: purchase history on signup

Members were surprised/unsettled to see their full purchase history when they signed up — felt like surveillance even though it’s just Square POS data reflected back. Lightened by seeing their starting level already being high from retroactive XP credit (“wait, I’m already level 5?”). The XP framing turns the data from dossier into reward. May need more intentional onboarding framing (progressive reveal, opt-in language) as membership scales beyond people who already trust Panat and Carrie personally.

Guild status

6 members (not counting Panat). In a good spot — ARG and quest features on the roadmap but not priority yet.

Store

Started using Edelweiss Omnibus — Ingram dropship + inventory sync with Square.

Shared inventory validation

Facebook post in “Bookstores using Square” — store owner asking about sharing inventory between Square accounts for consignment. Square has no native solution, workaround is manual CSV export/import. Validates the shared inventory thesis. See square-shared-inventory-pain.

Open

  • Merge PR #89
  • Kanka selfhosted — potential killer app for RPG campaign management
  • Purchase fulfillment email flow for RPG PDFs
  • Test e2e: have another member try write.dungeon.club