feat(tickets): persistance des filtres tickets entre redémarrages (#29)

Introduit le port UiPreferencesGateway et son adapter uiPreferences,
avec le module ticketFilterPersistence qui sauvegarde/restaure les
filtres (recherche, statut, sprint, agents) via useTickets,
useTicketSearch et useProjectAgents. Couvert par tests unitaires et
un test d'intégration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 07:45:50 +02:00
parent 9ee7290cde
commit 79f06c26d9
13 changed files with 793 additions and 20 deletions

View File

@ -88,6 +88,7 @@ import type {
TicketListQuery,
CreateTicketInput,
UpdateTicketInput,
UiPreferencesGateway,
ViewWindowClosed,
WindowGateway,
WorkStateGateway,
@ -2529,6 +2530,38 @@ export class MockTicketGateway implements TicketGateway {
}
}
/**
* In-memory {@link UiPreferencesGateway} for tests/dev (ticket #29). Mirrors the
* localStorage adapter's best-effort JSON round-trip without touching the DOM,
* so persisted-filter behaviour can be exercised offline.
*/
export class MockUiPreferencesGateway implements UiPreferencesGateway {
private readonly store = new Map<string, string>();
read(key: string): unknown {
const raw = this.store.get(key);
if (raw === undefined) return null;
try {
return JSON.parse(raw);
} catch {
this.store.delete(key);
return null;
}
}
write(key: string, value: unknown): void {
try {
this.store.set(key, JSON.stringify(value));
} catch {
/* best-effort */
}
}
remove(key: string): void {
this.store.delete(key);
}
}
function mostRestrictive(
project?: PermissionSet["fallback"],
agent?: PermissionSet["fallback"],
@ -2563,6 +2596,7 @@ export function createMockGateways(): Gateways {
conversation: new MockConversationGateway(),
ticket: new MockTicketGateway(systemGateway),
window: new MockWindowGateway(),
uiPreferences: new MockUiPreferencesGateway(),
};
}