New: Chapter settings and applicant notifications, requested by Infuriator. See the release test checklist before rollout.
How information moves
WoW addon records
Reads Blizzard-provided guild data and stores snapshots, logs, drafts, and audit results in SavedVariables.
WoW writes the file
SavedVariables reach disk after /reload, logout, or a normal game exit.
Desktop queues
The companion safely copies changed files, hashes them, archives them, and retries pending uploads.
Server receives
The API authenticates the chapter, rejects duplicates, stores snapshots, and summarizes them for the web dashboard.
Officer-facing functions
The addon never bypasses Blizzard protections. Protected actions still require a player click.
Audit checklist
Audit score: earned points divided by total possible points, shown as a percentage. The 10 categories are worth 10 points each (100 total). MOTD shares its 10 points between guild name followed by guild realm (5) and discord.gg/oldgods appearing after them (5). The Aegwynn chapter (guild club ID 397395211) expects Aegwynn in its MOTD while retaining its technical guild realm for uploads and other checks. Diagnostics show both realms. Other text may appear before, between, or after these parts; matching ignores case and repeated whitespace. Recruitment totals 10 and requires at least 26 days remaining. Calendar dungeon and officer meeting/pinned notes checks are 5 points each. New Member Info and missing in-game promotions are separate 5-point checks, each with its own confirmation and channel link. Failed or unchecked items earn no points.
Roster standards
scanRoster()Counts guild members, uses per-rank chapter inactivity limits (default 28 days), requires nonblank public notes, and checks configurable note prefixes (GM/officer default Disc: name). Inactive-member rows use a two-click secure removal action: the first click creates or updates the visible General Macro OGGA_Kick with a name-specific /gremove command, and the first button then reveals a separate Blizzard secure CONFIRM KICK button; the second click runs the prepared /gremove command. It never removes someone on the first click.
Message of the Day
scanMotd()Reads the guild MOTD and checks for guild name, guild realm, and discord.gg/oldgods in that order, allowing other text between them. If it does not, the audit offers a way to open guild controls.
Recruitment listing
scanRecruitment()Checks the guild’s in-game recruitment listing and reports whether its remaining active time meets the expected standard. Availability depends on Blizzard’s Club Finder data.
Applications
scanApplications()Requests the guild applicant list and reports whether applications are waiting for an officer. It does not approve or reject anyone automatically.
Bank cleanliness
scanBank()When guild-bank data is available, checks the donations area for items that are not pet cages. The officer still decides what should be moved.
Calendar standard
scanCalendar()Looks for required guild calendar coverage, including a dungeon activity and meeting evidence. Calendar results depend on which calendar data WoW has loaded.
Discord reminders
scanDiscordReminder()Creates checklist reminders and links for New_Member_Info and the missing in-game promotion channel. The addon cannot inspect Discord, so an officer marks these checks as passed.
Refresh and report
Audit:Refresh() · Audit:SaveReport()Refresh reruns the audit and redraws the checklist. Save Report writes a timestamped result into SavedVariables for later collection by the desktop companion.
Display, themes, and navigation
Audit:Render() · Audit:ApplyTheme() · Audit:SelectTab() · buildWindow()These functions construct the window, switch tabs, position checklist actions, apply dark or light colors, and render current results. They change presentation only—not guild data.
Recruiting
SearchCurrentZone() searches the current area. SearchRealmLevels() starts a realm-wide level search. StartWhoSearch(), RunNextWhoSearch(), and ProcessWhoResults() manage each /who request, read results, discard guilded players, and split capped result sets into smaller searches.StartWhoContinueCooldown() displays the throttle countdown. ContinueWhoScan() consumes one player click to send the next query. FinishWhoScan() closes the scan and creates a diagnostic log. This design respects Blizzard’s interaction and throttling rules.RenderRecruitingCandidates() draws the filtered, scrollable list. InviteNextCandidate() invites exactly one eligible person per click, records that invitation for the current session, and stores a longer-term anti-spam history so the same person is not repeatedly invited.isQuietZone() checks default and custom protected areas. PurgeQuietZoneCandidates() removes candidates found there. AddQuietZone() validates and saves a custom zone, while RenderQuietZones() explains and displays the list. SelectRecruitingSubtab() switches between Search and Quiet Zones.addWhoScanLog() records sends, responses, splits, timeouts, and decisions. currentWhoLogText() formats that history for copying. suppressBlizzardWhoUI() and restoreBlizzardWhoUI() prevent normal addon scans from needlessly leaving the Blizzard Who window open.Calendar
Prepare a repeating series
Audit:StartCalendarSeries()The form stays hidden until New Event is clicked. New Event clears the working draft. Repeat is off by default; selecting it enables the 7-day and 6-occurrence defaults. The function validates and saves the draft before creating anything.
Create one occurrence
Audit:CreateNextCalendarEvent()Uses one user click to create the next guild event. For a repeating event, it starts an 8-second cooldown after each successful submission and enables Continue when the next protected click is allowed.
Invitees and draft preview
AddCalendarDraftInvitee() · RenderCalendarDraft()Adds names to the draft and shows exactly what will be created, including recurrence and progress.
Future synchronization data
calendarEventsJson() · inviteesJson()Serialize calendar drafts and invitees into JSON-shaped text so the external companion and future central service can understand them.
Guild bank ledger
| Function | Plain-English purpose |
|---|---|
BeginGuildBankSession()EndGuildBankSession() | Recognizes when the bank opens and closes, creates a capture session, and schedules reads while Blizzard permits access. |
CaptureGuildBankLogs() | Reads available item and money transaction logs and converts them into normalized ledger records. |
CaptureGuildBankInventory() | Takes a read-only snapshot of visible bank tabs, slots, item links, counts, locks, and total bank money. |
StartBankInventoryQuery()ContinueBankInventoryQuery() | Requests bank tabs in stages because all tabs may not be available immediately. It continues until the accessible inventory is captured. |
ScheduleBankLogCapture()ScheduleBankInventoryCapture() | Waits briefly before reading so Blizzard has time to populate bank information. |
StoreBankBatch() | Deduplicates a group of bank events and saves only new records, preventing repeated scans from multiplying the same transaction. |
QueryGuildBankData() | Manual “Capture Now” entry point. It requests the newest logs and inventory while the guild bank is open. |
RenderBankPage() | Searches and filters the ledger by gold/item and deposit/withdrawal type, or switches to the current inventory view. |
bankJson() | Builds a portable JSON representation of transactions and inventory for copying or future synchronization. |
Roster and event history
Roster snapshots
readRosterSnapshot() · CaptureRosterSnapshot()Reads every current member and compares the new snapshot with the previous one. It records joins, departures, rank changes, level/class changes, and note changes. Large unexpected count changes are verified before being accepted.
Official guild-event log
ImportGuildEventLog() · CleanupRosterEventDuplicates()Imports Blizzard’s join, quit, invite, remove, promote, and demote events and removes duplicate observations.
Searchable roster
RenderRosterPage() · rosterSearchMatches()Displays members and searches names, public notes, officer notes, or both. Selecting a member reveals allowed actions and copy helpers.
Safe player actions
ConfigureRosterMemberActions() · createSecureRosterButton()Prepares Blizzard-secure buttons for promote, demote, group invite, or an armed-and-confirmed removal. These actions require a real click and respect combat restrictions and guild permissions.
Event viewer
RenderRosterEventPage() · rosterEventMatches()Filters event history by text and type and renders only 100 records per page, avoiding long-script errors for large guild histories.
Name cleanup and scheduling
normalizeRosterMemberName() · ScheduleRosterCapture()Collapses accidental repeated realm suffixes and delays snapshot reads until WoW has finished updating the roster.
Keeping files and data moving
| Component | What it does |
|---|---|
JsonConfigurationStore | Loads and atomically saves the WoW path, addon source, server URL, chapter key, and monitoring preferences in the user’s local application-data folder. |
WowDiscoveryService | Looks in common Windows, macOS, Linux, and Wine locations for WoW Retail, then finds every account’s OldGodsGuildAudit SavedVariables file. |
AddonManager | Compares SHA-256 hashes and updates only the addon’s Lua and TOC files. Atomic replacement avoids leaving half-written addon files. |
JsonIngestionQueue | Copies a SavedVariables file while WoW may have it open, hashes the stable copy, skips unchanged account snapshots, archives new copies, and records pending queue entries. |
QueueUploadMonitor | Every 15 seconds, submits pending archives to the configured server. Successful or already-known snapshots become Uploaded; network failures stay Pending for retry; authentication failures are clearly marked. |
MainViewModel | Runs discovery, settings, addon updates, SavedVariables scans, queue counters, status cards, activity messages, and the light/dark theme command shown by the desktop window. |
Receiving and viewing snapshots
Receive a snapshot
POST /api/v1/snapshotsRequires a chapter name, account, content, and matching X-Chapter-Key. It limits the payload size, stores a new snapshot, and returns the existing receipt for a duplicate.
Browse server data
GET /api/v1/chaptersGET /api/v1/chapters/{chapter}/snapshotsReturns chapter totals or recent snapshot metadata. The requested count is bounded so one call cannot return an unlimited result set.
Durable file storage
FileGuildSnapshotStoreHashes content, creates a stable account-and-hash ID, safely writes the Lua snapshot and JSON metadata, and summarizes stored chapters. Identical uploads do not create duplicates.
Dashboard and health
IndexModel · GET /healthThe Razor Pages dashboard shows chapter snapshot totals, account totals, and last receipt time. Health provides a simple monitoring check that the web process is responding.
Internal helper functions
These are supporting pieces rather than separate officer features.
trim, shortName, normalizeRecruitName, normalizeZoneName clean user/API text so matching is consistent.copyDefaults safely upgrades SavedVariables; addResult creates a checklist result; showCopyBox presents text for Ctrl+C.openGuildRoster, openCalendar, openGuildBank, and openRecruitment open Blizzard’s own protected interfaces.pruneInviteHistory removes expired anti-spam entries; getInviteHistoryCount reports how many remain; isLeaderRank identifies officer/GM ranks; daysOffline converts roster time fields to days.calendarTimePlusDays, calendarDateWithOffset, and calendarDateText calculate and display repeated dates.jsonEscape protects quotes and control characters; copyStringList copies user-entered invitee lists without sharing mutable tables.currentGuildKey, bankAbsoluteTimestamp, bankItemID, bankBaseKey, bankRecordMatches, and bankMoneyText identify, deduplicate, search, and display ledger data.createButton, clearPageWidgets, and the Build…Page functions create controls and recycle dynamic page content.Important operating limits
- WoW only writes SavedVariables to disk on
/reload, logout, or a normal exit. - Invites, guild management, and calendar creation may require one genuine player click per protected action.
- Bank, calendar, applicant, and roster information is only available when Blizzard exposes or loads it.
- The addon cannot read Discord; Discord checks remain officer-confirmed reminders.
- The initial web dashboard must receive user authentication, HTTPS, managed secrets, and production-grade database/object storage before public deployment.
Revision 0 · Updated 9/11/2026 10:39 AM by Legacy documentation