diff --git a/docs/code-bridge/requests/REQ-2026-04-15-subscriber-wiki-auth.md b/docs/code-bridge/requests/REQ-2026-04-15-subscriber-wiki-auth.md new file mode 100644 index 0000000..21b4b89 --- /dev/null +++ b/docs/code-bridge/requests/REQ-2026-04-15-subscriber-wiki-auth.md @@ -0,0 +1,94 @@ +# REQ-2026-04-15-subscriber-wiki-auth + +**From:** Chronicler #92 +**Date:** 2026-04-15 +**Priority:** HIGH +**Status:** PENDING +**Linked Task:** #138 — Subscriber Wiki Discord OAuth + Tier Access Control + +## Note from Michael + +Wiki.js is already deployed at subscribers.firefrostgaming.com but has no auth or content. This wires up access control so tier-gated content actually works. Same pattern as everything else — Discord OAuth already exists, Stripe webhook already fires, just need to add Wiki.js group sync to the flow. + +## What Needs to Be Built + +### 1. Wiki.js GraphQL API integration + +Create `src/services/wikijsSync.js`: + +```js +// Wiki.js uses GraphQL API at https://subscribers.firefrostgaming.com/graphql +// Auth via API key (stored in .env as WIKIJS_API_KEY) + +async function syncWikiUser(discordId, username, tierLevel) +// Creates user if not exists, updates group assignment if they do +// Group mapping: +// tier_level 1 (Awakened) → Wiki group: "Awakened" +// tier_level 2 (Elemental) → Wiki group: "Elemental" +// tier_level 3 (Knight) → Wiki group: "Knight" +// tier_level 4 (Master) → Wiki group: "Master" +// tier_level 5 (Legend) → Wiki group: "Legend" +// tier_level 6 (Sovereign) → Wiki group: "Sovereign" +``` + +### 2. Hook into existing Stripe webhook flow + +In `src/routes/stripe.js`, after the existing Discord role sync and LuckPerms sync, add: + +```js +// Sync Wiki.js user group (non-blocking, silent-fail) +wikijsSync.syncWikiUser(discordId, username, tierLevel) + .catch(err => console.error('[WikiSync] Failed:', err.message)); +``` + +### 3. Hook into lifecycle handlers (cancellation/grace) + +When a subscriber cancels or enters grace period, demote their Wiki.js group to Awakened — same as Discord role demotion. + +### 4. Add WIKIJS_API_KEY to .env.example + +Document the new env var. + +## Wiki.js GraphQL Mutations Needed + +```graphql +# Create user +mutation CreateUser($email: String!, $name: String!, $groups: [Int!]!) { + users { + create(email: $email, name: $name, passwordRaw: "", providerKey: "discord", groups: $groups) { + responseResult { succeeded message } + } + } +} + +# Update user groups +mutation UpdateUser($id: Int!, $groups: [Int!]!) { + users { + update(id: $id, groups: $groups) { + responseResult { succeeded message } + } + } +} + +# Search user by email +query FindUser($email: String!) { + users { + search(query: $email) { id email } + } +} +``` + +## Notes + +- Wiki.js user email = discordId@firefrost.local (unique, internal) +- Wiki.js groups must be pre-created manually (Awakened, Elemental, Knight, Master, Legend, Sovereign) — Michael does this in Wiki.js admin panel before deploy +- Silent-fail pattern — never let wiki sync break the Stripe webhook +- Log successes and failures to console for debugging +- WIKIJS_API_KEY generated in Wiki.js admin → API Access + +## Files to Touch + +- New: `src/services/wikijsSync.js` +- Modify: `src/routes/stripe.js` +- Modify: `src/routes/stripe.js` lifecycle handlers (cancellation/grace) +- Modify: `.env.example` (add WIKIJS_API_KEY)