I founded The Cantina Network, an online gaming community of more than 400 members, and build and operate the tools behind it: member accounts, roster planning, community automation and chat integrations. The work connects web development with identity, infrastructure, controlled delivery and a documented handoff.
I designed and built these tools myself, for our community. I work alongside the TCN team and consult other developers, while the code and architecture are my own.
01 / In practice
Tools for members and organisers.
Member accounts, season planning and raids
Members need to connect their game identity, choose characters and participate in a season. Guild organisers need a clear view of signups and attendance.
I built the React interfaces and APIs behind Accounts and Roster. Accounts owns provider connections and credentials; Roster uses scoped evidence alongside game-data lookups, then owns season choices, raids and attendance. Its dedicated raid bot connects signup and reminder workflows to Discord.
Account evidence flow
Member sign-in
TCN Accounts
Provider connection
Scoped evidence
WoW Roster
Current stateAccounts and Roster are live. Some sign-in and provider-connection paths are still being tested.
Officers drag players into groups and see role balance at a glance.Season signup in four short steps.
In practice / Interactive demo
WoW Roster: keep a raid ready.
Run a sample raid: mark Tide absent, swap players, change specializations or add a saved character. Review Auto-sort and group changes before applying them.
About this demoAn interactive local preview using fictional data, embedded in this portfolio. A working local adaptation of the raid planner, starting with four groups and 23 fictional signups. It includes saved-character selection, attendance, placements and raid settings. Accounts, game services and the raid bot are not connected. Changes reset when you reload.
A chat experience that fits the community
An independent chat service needs a familiar identity and usable access from the web and desktop, while remaining maintainable as its upstream product changes.
I customise the hosted Fluxer frontend and maintain a TCN adaptation of its Electron client. The work includes branded themes, validated server selection, separate desktop sessions and an offline chooser. Patch records explain each change, its upstream dependency and how to reapply and verify it.
Desktop app (in testing)
Fluxer client
TCN identity
Server selection
Separate sessions
Offline recovery
Current stateHosted Chat and its themes are live, with Chat’s own login. The desktop app works locally but is not released yet.
The Cantina Chat desktop app.
Community workflows across chat platforms
Community organisers need to connect participating Discord and Fluxer spaces, manage relay choices and understand what happened when an integration fails.
I built the Management Bot, its dashboard and durable relay workflow. Platform events enter an inbox/outbox system, with scoped consent and channel policy governing admission. Worker and lifecycle diagnostics make partial failures reviewable. This bot is separate from the Roster raid bot.
Text relay workflow
Discord / Fluxer gateway
Durable inbox
Consent & policy
Sync worker
Target adapter
Current stateAutomation and relay are live. Voice features still need longer-running testing.
From the raid plan to the game
A lineup planned on the website still has to be rebuilt by hand in the game. Organisers need the raid groups arranged and missing players invited without retyping anything.
I built TCN Assistant, a World of Warcraft addon for raid organisers. Officers copy a planned lineup from the roster in a small, strictly validated text format and paste it into the addon. It arranges the raid groups one verified move at a time, invites missing players in paced rounds and keeps track of who declined. The hand-off is copy and paste: the addon makes no network calls and saves nothing to disk.
Website to game hand-off
Roster lineup
Copy for WoW addon
Paste in TCN Assistant
Preview
Arrange & invite
Current stateIn in-game testing. Only the organiser needs it installed.
Selected surfaces
Interfaces and identity.
TCN AccountsMembers connect Battle.net once and control which apps may use it. Shown with demo data.
WoW Season RosterProject identity for the planning and membership-evidence tool.
02 / System
Separated services. Explicit contracts.
Accounts and Roster integrate with Authentik identity; Chat keeps its own local login. Each application owns its permissions and data. This is a capability map: the layers do not imply that every service shares a login or database.
EdgePublic DNS & edgeCloudflareTLS & routingNGINX Proxy Manager
IdentityApplication identity · OIDCAuthentik
Accounts & Roster integrationChat owns its local login
Security-sensitive topology, addresses, ports, identifiers and exact deployment counts are deliberately not represented.
03 / Selected capabilities
Applications and operations.
These are selected examples of my development and integration work. Fluxer, Authentik, AMP and the other upstream platforms retain their own authorship.
Built / adapted / engineered08 selected
Identity-linked member evidence
TCN Accounts
TypeScript · Fastify · React · PostgreSQL · OAuth
Admins search connections without seeing credentials.
Live; some provider sign-in paths still in testing
Season planning, raids, attendance and a dedicated raid bot
WoW Season Roster
React · Fastify · PostgreSQL · Accounts API · Battle.net
The season roster shows who signed up, their role and availability.Recurring raids prepare twelve weeks ahead.
Live; some account sign-in paths still in testing
In-game companion for raid organisers (WoW addon)
TCN Assistant
Officers copy a planned lineup from the roster website, paste it into the addon, and it arranges the raid groups, invites missing players in paced rounds and keeps track of who declined.
Lua · World of Warcraft Retail API · headless test suite
Paste the lineup, preview, then arrange the raid in game. Interface preview.
In in-game testing; only the organiser needs it installed
Community dashboard, automation and cross-platform relay
Management Bot
Node.js · TypeScript · Discord.js · PostgreSQL · LiveKitLive; voice features still in testing
Hosted customisation and an upstream desktop adaptation
Cantina Chat adaptations
Fluxer · React · Electron · patch maintenanceHosted themes live; desktop app not yet releasedSource on GitHub
Evidence-driven build and promotion path
TCN Delivery
Every image is scanned for known vulnerabilities before it can ship; a high or critical finding blocks the release.
GitHub Actions · containers · manifests · SBOM · TrivyUsed to release Accounts and Roster
Versioned identity policy and service registration
Authentik configuration
Blueprints · validation · environment gatesIn use for Accounts and Roster
Human-maintained game templates compiled for AMP
AMP template pipeline
Validation · generated deployment branch · AMP ADSLive and in useSource on GitHub
Integrated platforms / dependencies05 selected
Identity & ingress
Authentik and NGINX Proxy Manager provide identity integration, HTTPS and routing.
Third-party platforms I configure and operate
Service & game hosting
Proxmox isolates application services; AMP runs on a separate game-server host.
Infrastructure ownership and game-template integration
Community publishing
WordPress, the anniversary application and Strapi support public and administrative surfaces.
Separate applications and data boundaries
Documentation reader
Wiki.js hosts the documentation, including a developer handbook in review.
Hosted; handbook review and single sign-on in progress
External dependency
Sentinel remains an externally sourced production dependency.
Outside TCN development and maintenance
04 / Engineering
Delivery and handoff.
Accounts and Roster are released through a controlled delivery path, and every change is tested on a separate staging environment before members see it. Developer handbooks explain ownership, contracts and how to test each part, so another developer can take over.
Release flow
Nothing reaches members untested.
A separate staging environment mirrors the live layout service for service, on its own hardware. Every change is built once into a frozen release candidate, deployed to staging and checked by a person. The exact same files are then promoted to production. If something goes wrong, the previous version is kept ready to restore.
01ChangePull request with CI build, tests and image scan
02Release candidateBuilt once; images, manifest and file hashes frozen
03StagingSeparate environment on its own hardware, checked by a person
04Production gateGreen CI for that commit and a scan under 24 hours old
05MembersThe same files go live; the previous version stays ready
A failed build, scan or staging check goes back to the developer. Only the accepted, scanned candidate goes live.
Build once, promote the same bytes
Production receives the tested candidate unchanged, so what was tested is exactly what runs.
Fast staging
One command builds the candidate, replaces only the selected services and checks readiness. A change is testable on staging in about five minutes while the full CI run continues.
Rollback is designed in
The previous version stays in place, and a recovery workflow can restore any accepted release.
Database changes on their own
Deployments never run database migrations themselves. A migration is applied and verified as a separate step first.
Versioned releases
Each app keeps a release ledger with semantic versions, such as roster 1.15.0; staged candidates are numbered release candidates.
Real member data stays in production
Development, CI and staging run on synthetic data with a mock sign-in provider, which is also why the screenshots on this page are safe to share.
Evidence, never credentials
Apps get proof that you own a character, never your passwords or login tokens.
Accounts keeps provider credentials inside its own boundary. Other tools receive scoped, versioned evidence that answers a business question without inheriting access to the original account.
Keep application authority local
Each app decides for itself who may do what; no single system can override them all.
Accounts and Roster use Authentik identity while owning their own product permissions and data. Chat keeps its local login.
Durability before relay
A message between Discord and the chat is saved first, so nothing is lost if one side is down.
Cross-platform text events enter an inbox/outbox workflow before delivery. Workers retain progress and reviewable outcomes through partial failures, with unresolved delivery outcomes kept explicit.
Give data its own lifecycle
Disconnecting, withdrawing consent and deleting data are separate, deliberate actions.
Provider disconnect, revoked consent and account erasure are separate operations. Relay admission uses scoped consent; revocation does not universally recall queued messages. The documented voice design streams audio without retaining recordings, while operational metadata has its own lifecycle.
Immutable delivery evidence
Every release keeps a fixed record of exactly what was tested and shipped.
Reviewed build evidence and matched staging acceptance bind a release to its exact manifest and image digests. Delivery plans the change, promotes the frozen images and verifies the result independently. Schema and data changes receive separate review and rehearsal.
Maintain upstream adaptations
Changes to the open-source chat app are tracked as patches, so updates stay easy.
Chat remains a Fluxer-based product. Hosted and desktop changes have separate patch records covering purpose, upstream revisions, reapplication, verification and retirement. Attribution and a repeatable upgrade path are part of the work.
Human source, generated artifact
People edit the readable source; the files that run are generated from it automatically.
Game templates stay maintainable in a human-friendly hierarchy, then compile into the flat structure AMP can index. Generated deployment state never becomes the authoring source.
Make the system transferable
Handbooks and runbooks let someone else take over without asking the original author.
Service-owned developer handbooks explain user journeys, contracts, data boundaries and how to test each part. Handoff rehearsals from a clean copy of the source confirmed that the builds and tests can be reproduced.
Vulnerabilities stop at the door
Software with a known serious security problem cannot reach members.
Every container image is scanned before it can ship, and any high or critical finding fails the build. The same scan runs on the developer’s machine before code is pushed, and again every week on the live code, so newly published issues surface as a ticket instead of a surprise.
Automated security checks
Fixing a flagged package or base image is routine work, done in its own small change and shipped through staging like any other release.
Check
When it runs
What it does
Image scan (Trivy)
Every pull request, per production image
Fails on any high or critical finding and keeps the report as evidence
SBOM (Syft, SPDX)
Every pull request, per image
Lists every package inside each image
Local pre-push scan
Before every push, on the developer’s machine
Runs the same pinned scanner, so CI does not fail on something already known
Weekly scan
Every Monday on the main branch
Rebuilds and rescans; opens or updates an issue when new vulnerabilities appear
Production gate
Before promotion, and again right before apply
Requires a scan under 24 hours old with zero high or critical findings
Secret scanning
On every change
Blocks credentials from entering the repositories
Pinned dependencies
Always
CI actions are pinned to exact commits, base images to exact digests, and the lockfile must pass supply-chain checks
05 / Current state
Delivered and in progress.
Status as of .
Gated production releases of the roster since 1.0.0
25
Automated browser test scenarios, on desktop and mobile layouts
228
Unit test files across Accounts and Roster
86
From commit to testable on staging
~5 min
Live
Accounts and Roster, including the Roster raid bot
Management Bot automation, and hosted Fluxer-based Chat with community themes
Controlled releases through TCN Delivery, and the AMP template pipeline
Two community questionnaires in Roster, and a developer handbook in review
In development
TCN Assistant WoW addon: in in-game testing
Desktop Chat app: works locally, not yet released
Standalone Polls: being prepared for testing
Shared sign-in across the web apps: in development, not switched on
Still to finish
Remaining sign-in, provider-connection and permission paths
Voice features and longer-running integration tests
Consistent data retention and deletion across the services
Recovery testing for new releases, and final proofreading of the handbook
Interactive raid planner · fictional saved characters · changes stay in this demo
Drag to move or swap. Adjust works with keyboard and touch.
Try it: mark Tide absent to bring Moss off the bench, add a saved character, or drag a player to swap places.
Group 15/5
Stone✓ Available
Stone–Demo Realm · Warrior◆ Protection · Tank
Willow✓ Available
Willow–Demo Realm · Druid✚ Restoration · Healer
Ember✓ Available
Ember–Demo Realm · Mage⚔ Fire · Damage
Quill✓ Available
Quill–Demo Realm · Hunter⚔ Marksmanship · Damage
Dusk✓ Available
Dusk–Demo Realm · Priest⚔ Shadow · Damage
Group 25/5
Iron✓ Available
Iron–Demo Realm · Paladin◆ Protection · Tank
Brook✓ Available
Brook–Demo Realm · Shaman✚ Restoration · Healer
Spark✓ Available
Spark–Demo Realm · Shaman⚔ Elemental · Damage
Fern✓ Available
Fern–Demo Realm · Druid⚔ Balance · Damage
Rune✓ Available
Rune–Demo Realm · Mage⚔ Frost · Damage
Group 35/5
Flint✓ Available
Flint–Demo Realm · Warrior⚔ Fury · Damage
Solace✓ Available
Solace–Demo Realm · Priest✚ Holy · Healer
Argent✓ Available
Argent–Demo Realm · Paladin⚔ Retribution · Damage
Vale✓ Available
Vale–Demo Realm · Warlock⚔ Affliction · Damage
Echo✓ Available
Echo–Demo Realm · Rogue⚔ Subtlety · Damage
Group 45/5
Glint✓ Available
Glint–Demo Realm · Mage⚔ Arcane · Damage
Tide✓ Available
Tide–Demo Realm · Evoker✚ Preservation · Healer
Coral✓ Available
Coral–Demo Realm · Shaman⚔ Enhancement · Damage
Thistle◷ Tentative
Thistle–Demo Realm · Monk⚔ Windwalker · Damage
Lyric◷ Awaiting confirmation
Lyric–Demo Realm · Evoker✦ Augmentation · Support
Benched 2
Moss✓ Available
Moss–Demo Realm · Monk✚ Mistweaver · Healer
Bastion✓ Available
Bastion–Demo Realm · Death Knight◆ Blood · Tank
Absent 1
Rowan× Absent
Rowan–Demo Realm · Hunter⚔ Beast Mastery · Damage
Available, Tentative and Late retain a place. Absent releases it. Auto-sort reserves two tank places and balances healers against damage/support; manual moves switch it off. Sample changes reset on reload.