chore: add pre-commit hooks, tighten ESLint, activate Sentry DSN, publish CI coverage (Phase 1)
- Install husky v9 + lint-staged: pre-commit runs eslint --fix and prettier on staged files - Tighten ESLint base config: no-console→error, ban-ts-comment (ts-ignore banned, ts-expect-error with description allowed), reportUnusedDisableDirectives→error - Migrate web app from deprecated `next lint` to `eslint src/` with flat config and react-hooks plugin - Convert all 5 @ts-ignore to @ts-expect-error with descriptions, remove stale disable comments - Add NEXT_PUBLIC_SENTRY_DSN to docker-compose.prod.yml and .env.example - Add coverage artifact upload step to CI test job - Pre-existing violations (102 warnings) downgraded to warn in web config for Phase 2 cleanup Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,8 @@ import { loadRoleDefaults } from "@capakraken/api";
|
||||
import { deriveUserSseSubscription, eventBus } from "@capakraken/api/sse";
|
||||
import { startReminderScheduler } from "@capakraken/api/lib/reminder-scheduler";
|
||||
import { prisma } from "@capakraken/db";
|
||||
import { SSE_EVENT_TYPES, SystemRole, type PermissionOverrides } from "@capakraken/shared";
|
||||
import type { SystemRole } from "@capakraken/shared";
|
||||
import { SSE_EVENT_TYPES, type PermissionOverrides } from "@capakraken/shared";
|
||||
import { auth } from "~/server/auth.js";
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
@@ -59,26 +60,27 @@ export async function GET() {
|
||||
start(controller) {
|
||||
// Send initial connection confirmation
|
||||
controller.enqueue(
|
||||
encoder.encode(`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.PING, timestamp: new Date().toISOString() })}\n\n`),
|
||||
encoder.encode(
|
||||
`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.PING, timestamp: new Date().toISOString() })}\n\n`,
|
||||
),
|
||||
);
|
||||
|
||||
// Subscribe to event bus
|
||||
const unsubscribe = eventBus.subscribe(
|
||||
(event) => {
|
||||
try {
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\n\n`));
|
||||
} catch {
|
||||
// Client disconnected
|
||||
}
|
||||
},
|
||||
subscription,
|
||||
);
|
||||
const unsubscribe = eventBus.subscribe((event) => {
|
||||
try {
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\n\n`));
|
||||
} catch {
|
||||
// Client disconnected
|
||||
}
|
||||
}, subscription);
|
||||
|
||||
// Heartbeat every 30 seconds
|
||||
const heartbeat = setInterval(() => {
|
||||
try {
|
||||
controller.enqueue(
|
||||
encoder.encode(`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.PING, timestamp: new Date().toISOString() })}\n\n`),
|
||||
encoder.encode(
|
||||
`data: ${JSON.stringify({ type: SSE_EVENT_TYPES.PING, timestamp: new Date().toISOString() })}\n\n`,
|
||||
),
|
||||
);
|
||||
} catch {
|
||||
clearInterval(heartbeat);
|
||||
|
||||
Reference in New Issue
Block a user