feat(p10): archivage automatique des sessions terminées (rétention configurable)
- DB: migration #10 (sessions.archived_at + index), helpers archive/unarchive/archiveExpired (soft-archive, jamais de DELETE) - core/retention-settings.ts: session_retention_days (défaut 30, 0=jamais, 1-3650) + session_purge_days (off) - core/session-archive.ts: scheduler start/stop/sweep (calqué DiscoveryService), câblé dans runDaemon - pty-manager.list({includeArchived}) + SessionSummary.archived + emitHistoricalUpdate - routes: GET /sessions?includeArchived, POST/DELETE /sessions/:id/archive, POST /sessions/archive-now - protocole additif: message WS session_archived (relayé par la gateway, abonnés 'sessions') - settings: retentionDays/purgeDays exposés et validés dans PATCH /settings - web: store sessions (showArchived + archive/unarchive), SessionsListView (toggle/badge/actions), SettingsView (slider rétention), i18n EN+FR - tests: retention-settings + session-archive (vitest) + settings-routes étendu ; acceptance-p10.mjs (sweep, event WS, resume d'une session archivée → 201, rétention=0)
This commit is contained in:
@@ -10,6 +10,7 @@ import type { Db } from './db/index.js';
|
||||
import { AuthService, LoginRateLimiter, type AuthContext } from './auth/service.js';
|
||||
import { PtyManager } from './core/pty-manager.js';
|
||||
import { DiscoveryService } from './core/discovery-service.js';
|
||||
import { SessionArchiveService } from './core/session-archive.js';
|
||||
import { WorktreeManager } from './core/worktree-manager.js';
|
||||
import { RepoDiscoveryService } from './core/repo-discovery.js';
|
||||
import { GroupManager } from './core/group-manager.js';
|
||||
@@ -73,6 +74,7 @@ export interface AppBundle {
|
||||
auth: AuthService;
|
||||
manager: PtyManager;
|
||||
discovery: DiscoveryService;
|
||||
sessionArchive: SessionArchiveService;
|
||||
repoDiscovery: RepoDiscoveryService;
|
||||
worktrees: WorktreeManager;
|
||||
groups: GroupManager;
|
||||
@@ -94,6 +96,8 @@ export function buildApp(config: Config, db: Db, serverVersion: string): AppBund
|
||||
projectsDir: config.claudeProjectsDir,
|
||||
sessionsDir: config.claudeSessionsDir,
|
||||
});
|
||||
// Archivage auto des sessions terminées (P10). Démarré dans runDaemon() — jamais ici (tests).
|
||||
const sessionArchive = new SessionArchiveService({ db });
|
||||
// Watcher FS temps réel (P7) : armé à la demande sur les worktrees regardés via les commandes
|
||||
// WS watch/unwatch. closeAll() au drain (libération des descripteurs).
|
||||
const fsWatcher = new FsWatcherService();
|
||||
@@ -177,7 +181,7 @@ export function buildApp(config: Config, db: Db, serverVersion: string): AppBund
|
||||
});
|
||||
|
||||
registerAuthRoutes(app, auth, limiter, serverVersion, db);
|
||||
registerSessionRoutes(app, manager, discovery, db);
|
||||
registerSessionRoutes(app, manager, discovery, sessionArchive, db);
|
||||
registerProjectRoutes(app, manager, db);
|
||||
registerRepoRoutes(app, worktrees, db);
|
||||
registerGroupRoutes(app, groups, db, worktrees, manager);
|
||||
@@ -192,7 +196,7 @@ export function buildApp(config: Config, db: Db, serverVersion: string): AppBund
|
||||
// La route websocket doit être déclarée APRÈS le chargement du plugin (contexte
|
||||
// encapsulé) — sinon le handler reçoit la signature REST (request, reply).
|
||||
void app.register(async (scoped) => {
|
||||
registerWsGateway(scoped, manager, discovery, worktrees, groups, serverVersion);
|
||||
registerWsGateway(scoped, manager, discovery, sessionArchive, worktrees, groups, serverVersion);
|
||||
});
|
||||
|
||||
// SPA buildée embarquée dans le paquet npm (public/) — absente en dev (vite dev sert le front)
|
||||
@@ -207,5 +211,5 @@ export function buildApp(config: Config, db: Db, serverVersion: string): AppBund
|
||||
});
|
||||
}
|
||||
|
||||
return { app, auth, manager, discovery, repoDiscovery, worktrees, groups, push, fsWatcher };
|
||||
return { app, auth, manager, discovery, sessionArchive, repoDiscovery, worktrees, groups, push, fsWatcher };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user