refactor(voice): remove heartbeat and debug logging sessions (#2121)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-30 21:08:46 +02:00
1 parent 36b85512c6
commit b4d9cdc584
33 files changed
+566 -3783

No files matched your search

@@ -1,11 +1,6 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
coerceNumberFromString,
createStringType,
SnowflakeStringType,
SnowflakeType,
} from '@fluxer/schema/src/primitives/SchemaPrimitives';
import {createStringType, SnowflakeStringType, SnowflakeType} from '@fluxer/schema/src/primitives/SchemaPrimitives';
import {z} from 'zod';
function areServerCoordinatesPaired(
@@ -266,64 +261,6 @@ export const GetVoiceServerResponse = z.object({
export type GetVoiceServerResponse = z.infer<typeof GetVoiceServerResponse>;
const DiagnosticsTimestampMs = coerceNumberFromString(z.number().int().min(0).max(8640000000000000)).describe(
'Unix timestamp in milliseconds',
);
const DiagnosticsSessionId = z
.string()
.min(1)
.max(128)
.regex(/^[A-Za-z0-9_.:-]+$/)
.optional()
.describe('Optional voice diagnostics session id filter');
export const VoiceDiagnosticsQueryRequest = z
.object({
channel_id: SnowflakeStringType.describe('Channel id to query diagnostics for'),
start_ms: DiagnosticsTimestampMs.describe('Inclusive start timestamp in milliseconds'),
end_ms: DiagnosticsTimestampMs.describe('Inclusive end timestamp in milliseconds'),
session_id: DiagnosticsSessionId,
limit_objects: coerceNumberFromString(z.number().int().min(1).max(5000))
.optional()
.default(1000)
.describe('Maximum matching S3 objects to include'),
})
.superRefine((value, ctx) => {
if (value.end_ms < value.start_ms) {
ctx.addIssue({
code: 'custom',
path: ['end_ms'],
message: 'INVALID_FORMAT',
});
}
const maxRangeMs = 31 * 24 * 60 * 60 * 1000;
if (value.end_ms - value.start_ms > maxRangeMs) {
ctx.addIssue({
code: 'custom',
path: ['end_ms'],
message: 'INVALID_FORMAT',
});
}
});
export type VoiceDiagnosticsQueryRequest = z.infer<typeof VoiceDiagnosticsQueryRequest>;
const VoiceDiagnosticsObjectResponse = z.object({
key: z.string().describe('S3 object key'),
session_id: z.string().describe('Voice diagnostics session id'),
start_ns: z.string().describe('First client event timestamp in the object, in nanoseconds'),
end_ns: z.string().describe('Last client event timestamp in the object, in nanoseconds'),
last_modified: z.iso.datetime().nullable().describe('S3 object last-modified timestamp'),
});
export const VoiceDiagnosticsObjectListResponse = z.object({
bucket: z.string().describe('Diagnostics S3 bucket'),
objects: z.array(VoiceDiagnosticsObjectResponse).describe('Matching diagnostics objects'),
});
export type VoiceDiagnosticsObjectListResponse = z.infer<typeof VoiceDiagnosticsObjectListResponse>;
export const CreateVoiceServerResponse = z.object({
server: VoiceServerAdminResponse.describe('Created voice server'),
});
@@ -24,7 +24,6 @@ import {createBase64StringType} from '@fluxer/schema/src/primitives/FileValidato
import {ContentWarningLevelSchema} from '@fluxer/schema/src/primitives/GuildValidators';
import {QueryBooleanType} from '@fluxer/schema/src/primitives/QueryValidators';
import {
coerceNumberFromString,
createNamedLiteral,
createNamedLiteralUnion,
createStringType,
@@ -292,46 +291,6 @@ export const CallRingBodySchema = z.object({
export type CallRingBodySchema = z.infer<typeof CallRingBodySchema>;
export const VoiceDebugLoggingToggleBodySchema = z.object({
enabled: z.boolean().describe('Whether voice debug logging should be active for this channel'),
duration_ms: coerceNumberFromString(z.number().int().min(60000).max(14400000))
.optional()
.describe('Optional activation duration in milliseconds. Defaults to one hour and is capped at four hours.'),
});
export type VoiceDebugLoggingToggleBodySchema = z.infer<typeof VoiceDebugLoggingToggleBodySchema>;
const VoiceDebugLoggingTimestampNs = z
.string()
.regex(/^[0-9]{1,32}$/)
.describe('Nanosecond timestamp encoded as an unsigned decimal string');
export const VoiceDebugLoggingEventSchema = z
.object({
type: createStringType(1, 128).describe('Client-side diagnostic event type'),
timestamp_ns: VoiceDebugLoggingTimestampNs.describe('Client wall-clock Unix timestamp in nanoseconds'),
monotonic_ns: VoiceDebugLoggingTimestampNs.optional().describe('Client monotonic timestamp in nanoseconds'),
data: z.record(z.string(), z.unknown()).optional().describe('Event-specific diagnostic payload'),
})
.passthrough();
export type VoiceDebugLoggingEventSchema = z.infer<typeof VoiceDebugLoggingEventSchema>;
export const VoiceDebugLoggingEventsBodySchema = z.object({
session_id: createStringType(1, 128).describe('Active voice debug logging session id'),
connection_id: createStringType(1, 128).optional().describe('Client voice connection id'),
participant_identity: createStringType(1, 256).optional().describe('LiveKit participant identity'),
events: z.array(VoiceDebugLoggingEventSchema).min(1).max(200).describe('NDJSON batch events to store'),
});
export type VoiceDebugLoggingEventsBodySchema = z.infer<typeof VoiceDebugLoggingEventsBodySchema>;
export const VoicePresenceHeartbeatBodySchema = z.object({
connection_id: createStringType(1, 128).describe('Client voice connection id'),
});
export type VoicePresenceHeartbeatBodySchema = z.infer<typeof VoicePresenceHeartbeatBodySchema>;
export const StreamUpdateBodySchema = z.object({
region: createStringType(RTC_REGION_ID_MIN_LENGTH, RTC_REGION_ID_MAX_LENGTH)
.optional()
@@ -47,46 +47,6 @@ export const CallEligibilityResponse = z.object({
export type CallEligibilityResponse = z.infer<typeof CallEligibilityResponse>;
export const VoiceDebugLoggingStatusResponse = z.object({
active: z.boolean().describe('Whether clients in this channel should currently send voice diagnostics'),
session_id: z.string().nullable().describe('Current debug logging session id, if active'),
activated_by_user_id: SnowflakeStringType.nullable().describe('Staff user that activated the session, if active'),
started_at_ms: z.number().int().nonnegative().nullable().describe('Session start Unix timestamp in milliseconds'),
expires_at_ms: z
.number()
.int()
.nonnegative()
.nullable()
.describe('Session expiration Unix timestamp in milliseconds'),
poll_interval_ms: Int32Type.describe('Recommended client polling interval in milliseconds'),
upload_interval_ms: Int32Type.describe('Recommended client telemetry batch upload interval in milliseconds'),
});
export type VoiceDebugLoggingStatusResponse = z.infer<typeof VoiceDebugLoggingStatusResponse>;
export const VoiceDebugLoggingEventsResponse = z.object({
accepted: z.boolean().describe('Whether the telemetry batch was accepted for storage'),
active: z.boolean().describe('Whether the server still considers this logging session active'),
stored_event_count: Int32Type.describe('Number of events written to diagnostics storage'),
});
export type VoiceDebugLoggingEventsResponse = z.infer<typeof VoiceDebugLoggingEventsResponse>;
export const VoicePresenceHeartbeatResponse = z.object({
ok: z.boolean().describe('Whether the heartbeat was accepted'),
heartbeat_interval_ms: Int32Type.describe('Recommended client heartbeat interval in milliseconds'),
heartbeat_ttl_ms: Int32Type.describe('Server-side heartbeat expiration window in milliseconds'),
expires_at_ms: z.number().int().nonnegative().describe('Unix timestamp in milliseconds when this heartbeat expires'),
});
export type VoicePresenceHeartbeatResponse = z.infer<typeof VoicePresenceHeartbeatResponse>;
export const VoicePresenceHeartbeatEndResponse = z.object({
ok: z.boolean().describe('Whether the heartbeat was ended'),
});
export type VoicePresenceHeartbeatEndResponse = z.infer<typeof VoicePresenceHeartbeatEndResponse>;
export const ChannelResponse = z.object({
id: SnowflakeStringType.describe('The unique identifier (snowflake) for this channel'),
guild_id: SnowflakeStringType.optional().describe('The ID of the guild this channel belongs to'),