deploy #2
@@ -94,18 +94,25 @@ export function TicketCategoriesManager({ guildId, initialCategories }: TicketCa
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
name: category.name,
|
||||
description: category.description,
|
||||
emoji: category.emoji,
|
||||
description: category.description?.trim() ? category.description : null,
|
||||
emoji: category.emoji?.trim() ? category.emoji : null,
|
||||
supportRoleIds: category.supportRoleIds
|
||||
})
|
||||
});
|
||||
const body = (await response.json().catch(() => null)) as
|
||||
| (TicketCategoryDashboard & { error?: string; code?: string })
|
||||
| null;
|
||||
if (!response.ok || !body) {
|
||||
if (!response.ok || !body || !body.id) {
|
||||
toast.error(panelSyncErrorMessage(body?.code, body?.error, t));
|
||||
return;
|
||||
}
|
||||
setCategories((prev) =>
|
||||
prev.map((entry) =>
|
||||
entry.clientKey === category.clientKey
|
||||
? { ...body, clientKey: entry.clientKey, saving: false }
|
||||
: entry
|
||||
)
|
||||
);
|
||||
toast.success(t('common.saveSuccess'));
|
||||
} catch {
|
||||
toast.error(t('common.saveError'));
|
||||
|
||||
@@ -105,7 +105,14 @@ async function maybeSyncTicketPanel(guildId: string): Promise<void> {
|
||||
if (!config?.enabled || !config.panelChannelId) {
|
||||
return;
|
||||
}
|
||||
await syncTicketPanel(guildId);
|
||||
// Category CRUD must succeed even if Discord panel sync fails — otherwise
|
||||
// support roles / category fields appear "unsaved" in the UI while already
|
||||
// persisted in Postgres.
|
||||
try {
|
||||
await syncTicketPanel(guildId);
|
||||
} catch (error) {
|
||||
console.warn('[tickets] panel sync after category change failed', { guildId, error });
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateTicketConfigDashboard(
|
||||
|
||||
@@ -533,6 +533,21 @@
|
||||
- [ ] Close aus Dashboard → Ticket verschwindet aus der Liste, Kanal/Thread wird geschlossen
|
||||
- [ ] Refresh-Button aktualisiert die Liste
|
||||
|
||||
## Post-Phase – Ticket Support-Rollen Speichern (Bugfix)
|
||||
|
||||
### Abgeschlossen (Code)
|
||||
|
||||
- Root cause: Kategorie-Save warf Fehler wenn Panel-Sync scheiterte → UI „Speichern fehlgeschlagen“, obwohl `supportRoleIds` schon in Postgres lagen
|
||||
- `maybeSyncTicketPanel` fängt Sync-Fehler ab; Kategorie-CRUD bleibt erfolgreich
|
||||
- Nach Speichern: Response inkl. `supportRoleIds` in die UI übernommen
|
||||
- Zod: `supportRoleIds` jetzt `SnowflakeSchema[]`
|
||||
|
||||
### Manuell testen
|
||||
|
||||
- [ ] Kategorie: Support-Rolle wählen → Speichern → Erfolgstoast
|
||||
- [ ] Seite neu laden → Rolle ist noch ausgewählt
|
||||
- [ ] Neues Ticket → Support-Rolle wird gepingt / in Thread aufgenommen
|
||||
|
||||
## Post-Phase – Ban/Kick-Reason Logging + Verification Fail Event (Status: implementiert)
|
||||
|
||||
### Abgeschlossen (Code)
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
SuggestionActionSchema,
|
||||
TagDashboardCreateSchema,
|
||||
TicketCategoryDashboardCreateSchema,
|
||||
TicketCategoryDashboardUpdateSchema,
|
||||
TicketConfigDashboardPatchSchema,
|
||||
WelcomeConfigDashboardPatchSchema
|
||||
} from './dashboard.js';
|
||||
@@ -99,6 +100,22 @@ describe('dashboard schemas', () => {
|
||||
expect(parsed.supportRoleIds).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('validates ticket category update with support roles', () => {
|
||||
const parsed = TicketCategoryDashboardUpdateSchema.parse({
|
||||
supportRoleIds: ['123456789012345678', '234567890123456789']
|
||||
});
|
||||
expect(parsed.supportRoleIds).toEqual(['123456789012345678', '234567890123456789']);
|
||||
});
|
||||
|
||||
it('rejects invalid support role ids on ticket category create', () => {
|
||||
expect(() =>
|
||||
TicketCategoryDashboardCreateSchema.parse({
|
||||
name: 'Support',
|
||||
supportRoleIds: ['not-a-snowflake']
|
||||
})
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
it('validates giveaway creation input', () => {
|
||||
const parsed = GiveawayCreateDashboardSchema.parse({
|
||||
channelId: '123456789012345678',
|
||||
|
||||
@@ -403,7 +403,7 @@ export const TicketCategoryDashboardSchema = z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
description: z.string().max(500).nullable().optional(),
|
||||
emoji: z.string().max(80).nullable().optional(),
|
||||
supportRoleIds: z.array(z.string())
|
||||
supportRoleIds: z.array(SnowflakeSchema)
|
||||
});
|
||||
export type TicketCategoryDashboard = z.infer<typeof TicketCategoryDashboardSchema>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user