원클릭으로
guild-pages
Guild Pages feature for Chronicle - customizable public pages for guilds with drag-drop panel editor
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Guild Pages feature for Chronicle - customizable public pages for guilds with drag-drop panel editor
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
How the `dbcdata import` loader is structured and how to add a new game-data importer that uploads into a Chronicle dataset. Use when adding/modifying an Importer in scripts/dbcdata/cli, wiring a new DBC upload endpoint in api/gamedataapi, or migrating a game-data type (spells, items, talents, creatures) from compiled-in dbcmem to a database-backed dataset.
Chronicle's multi-tenant branding and CSS theming system. Covers the Branding struct, server-side CSS injection via Go templates, the ThemeEditor component, and how branding flows from database → API → HTML template → React components. Use when: modifying branding fields, adding theme knobs, changing how logos/colors/titles render, or debugging tenant vs site-level branding resolution.
AzerothCore ScriptAI hook system documentation. Covers the Observer pattern, creating new ScriptObject types, implementing hooks in ScriptMgr, naming conventions, and advanced patterns (filtering via references/bool returns, module-internal hooks). Use when: adding hooks to AzerothCore, creating modules, or working with ScriptMgr.
Multi-server build pipeline for Chronicle. Each WoW server (Turtle, Epoch, etc.) produces its own binary via Go build tags, its own Docker image, and its own Railway deployment. Covers the dbcmem driver-registration pattern, Dockerfile SERVER arg, CI matrix strategy, and how to add a new server.
Generate static Go code from WoW DBC files
Rankings and leaderboard system for Chronicle. Covers speedrun tracking (parser-side kill detection), leaderboard queries with version filtering, admin-configurable version requirements, and the semver encoding scheme for SQL-side comparison. Use when: adding ranking types, modifying speedrun rules, changing version requirements, or working with the leaderboard API/UI.
| name | guild-pages |
| description | Guild Pages feature for Chronicle - customizable public pages for guilds with drag-drop panel editor |
| globs | ["api/guild_pages.go","api/chroniclesdk/guild_page.go","database/queries/guild_pages.sql","database/migrations/*guild_pages*","frontend/chronicle/src/pages/GuildPage/**"] |
Guild Pages allow guilds to create customizable public pages showcasing their raid progress, roster, and statistics.
┌─────────────────────────────────────────────────────────────────┐
│ Frontend │
├─────────────────────────────────────────────────────────────────┤
│ GuildPage.tsx (viewer) │ GuildPageEditor.tsx (editor) │
│ - Public view │ - Drag-drop layout │
│ - Device filtering │ - Tab/panel management │
│ - Tab navigation │ - Config modals │
├─────────────────────────────────────────────────────────────────┤
│ components/ │ panels/ │
│ - GuildPageCanvas │ - RecentRaids, Roster, Progress │
│ - TabBar │ - Stats, Markdown, Leaderboard │
│ - AddPanelDrawer │ - registry.ts (panel definitions) │
│ - PanelConfigModal │ - types.ts (GuildPanelDefinition) │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Backend API │
├─────────────────────────────────────────────────────────────────┤
│ api/guild_pages.go │ api/chroniclesdk/guild_page.go │
│ - ListGuilds │ - GuildPageConfig │
│ - GetGuildPage │ - GuildPageTab │
│ - UpsertGuildPage │ - GuildPagePanel │
│ - Tab CRUD │ - DeviceVisibility │
│ - Admin member mgmt │ - Request/Response types │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Database │
├─────────────────────────────────────────────────────────────────┤
│ guild_members │ Links users to guilds (edit permissions) │
│ guild_pages │ Page config (theme, is_public) │
│ guild_page_tabs │ Tabs with label, slug, sort_order │
│ guild_page_panels │ Panels with type, config JSON, position │
└─────────────────────────────────────────────────────────────────┘
-- guild_members: Users who can edit a guild's page
CREATE TABLE guild_members (
id UUID PRIMARY KEY,
guild_id UUID REFERENCES guilds(id),
user_id UUID REFERENCES users(id),
joined_at TIMESTAMPTZ,
UNIQUE(guild_id, user_id)
);
-- guild_pages: Main page configuration
CREATE TABLE guild_pages (
id UUID PRIMARY KEY,
guild_id UUID REFERENCES guilds(id) UNIQUE,
theme JSONB DEFAULT '{}'
);
-- guild_page_tabs: Multiple tabs per page
CREATE TABLE guild_page_tabs (
id UUID PRIMARY KEY,
page_id UUID REFERENCES guild_pages(id),
label TEXT,
slug TEXT,
sort_order INTEGER,
UNIQUE(page_id, slug)
);
-- guild_page_panels: Panels with grid position
CREATE TABLE guild_page_panels (
id UUID PRIMARY KEY,
tab_id UUID REFERENCES guild_page_tabs(id),
panel_type TEXT,
config JSONB DEFAULT '{}',
position JSONB DEFAULT '{"x":0,"y":0,"w":6,"h":2}'
);
frontend/chronicle/src/pages/GuildPage/panels/:// MyPanel.tsx
import type { GuildPanelDefinition } from "./types";
import { SomeIcon } from "lucide-react";
interface MyPanelConfig {
someSetting: string;
showSomething: boolean;
}
export const myPanelDefinition: GuildPanelDefinition<MyPanelConfig> = {
type: "my_panel",
label: "My Panel",
icon: <SomeIcon className="h-4 w-4" />,
description: "Description shown in panel picker",
defaultSize: { w: 6, h: 2 },
minSize: { w: 3, h: 2 },
maxSize: { w: 12, h: 6 },
configSchema: [
{
name: "someSetting",
label: "Some Setting",
type: "text", // "text" | "number" | "select" | "boolean" | "textarea"
placeholder: "Enter value...",
},
{
name: "showSomething",
label: "Show Something",
type: "boolean",
defaultValue: true,
},
],
defaultConfig: {
someSetting: "",
showSomething: true,
},
render: ({ guild, config, position, isEditing }) => {
// Return panel content JSX
// Use fake/stub data for now - real API will come later
return (
<div>
<p>Guild: {guild.name}</p>
<p>Setting: {config.someSetting}</p>
</div>
);
},
};
import { myPanelDefinition } from "./MyPanel";
export const PANEL_REGISTRY: AnyPanelDefinition[] = [
// ... existing panels
myPanelDefinition,
];
Tabs and panels support device-specific visibility:
type DeviceVisibility = "all" | "desktop" | "mobile";
GuildPage.tsx): Filters tabs/panels based on useIsMobile()GET /api/v1/g - List guilds (with page status)
GET /api/v1/g/{guildID} - Get guild info
GET /api/v1/g/{guildID}/page - Get full page config
PUT /api/v1/g/{guildID}/page - Upsert page (auth required)
POST /api/v1/g/{guildID}/page/tabs - Create tab
PUT /api/v1/g/{guildID}/page/tabs/{tabID} - Update tab + panels
DELETE /api/v1/g/{guildID}/page/tabs/{tabID} - Delete tab
PUT /api/v1/g/{guildID}/page/tabs/reorder - Reorder tabs
GET /api/v1/g/{guildID} - Public page endpoint
# Admin only
POST /api/v1/admin/g/{guildID}/members - Add member
DELETE /api/v1/admin/g/{guildID}/members/{userID} - Remove member
Implemented:
Using stub data:
fetchGuildPage() returns FAKE_GUILD_PAGE constantTODO:
| File | Purpose |
|---|---|
api/guild_pages.go | API handlers |
api/chroniclesdk/guild_page.go | SDK types (generates TS) |
database/queries/guild_pages.sql | SQL queries |
frontend/.../GuildPage/GuildPage.tsx | Public viewer |
frontend/.../GuildPage/GuildPageEditor.tsx | Editor |
frontend/.../GuildPage/panels/registry.ts | Panel definitions |
frontend/.../GuildPage/panels/types.ts | TypeScript interfaces |