Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 3x 3x 3x 3x 4x 1x 1x 4x | /**
* Doorbell → socket fan-out (Phase 2a, #8.4), modeled on
* `lib/classroom/socket-emitter.ts`.
*
* TENANT SCOPING IS THE WHOLE POINT: a ring resolves to exactly one owning
* user (the connection row's userId) and emits to that user's room only —
* `io.to('user:' + userId)`, never a global `io.emit`. Another account's
* browser must never observe that this user's printer did anything.
*/
import { getSocketIO } from '@/lib/socket-io'
import { PRINT_JOB_UPDATED_EVENT, type PrintJobUpdatedEvent } from './ring-events'
/**
* Emit a print-job-updated hint to the owning user's room. Payload is
* identifiers only (see ring-events.ts) — the client re-reads real state
* through the authenticated proxy.
*/
export async function emitPrintJobUpdated(
userId: string,
payload: PrintJobUpdatedEvent
): Promise<void> {
const io = await getSocketIO()
if (!io) return
try {
io.to(`user:${userId}`).emit(PRINT_JOB_UPDATED_EVENT, payload)
console.log(`[PrintRing] ${PRINT_JOB_UPDATED_EVENT} -> user:${userId}`)
} catch (error) {
console.error('[PrintRing] Failed to emit print-job-updated:', error)
}
}
|