refactor(push): retire the push service delivery experiment (#3000)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-28 00:45:22 +02:00
1 parent 2a9e25c788
commit 5b280898c5
83 files changed
+1882 -10066

No files matched your search

@@ -23,10 +23,7 @@ import {
GatewayRolloutConfigResponse,
GatewayRolloutConfigUpdateRequest,
} from '@fluxer/schema/src/domains/admin/GatewayRolloutSchemas';
import {
PushServiceDeliveryConfigResponse,
PushServiceDeliveryConfigUpdateRequest,
} from '@fluxer/schema/src/domains/admin/PushServiceDeliverySchemas';
import {PushRelayConfigResponse, PushRelayConfigUpdateRequest} from '@fluxer/schema/src/domains/admin/PushRelaySchemas';
import {
VoiceNoiseSuppressionConfigResponse,
VoiceNoiseSuppressionConfigUpdateRequest,
@@ -656,7 +653,7 @@ export const InstanceConfigResponse = z.object({
sso: SsoConfigResponse,
gateway_rollout: GatewayRolloutConfigResponse,
voice_noise_suppression: VoiceNoiseSuppressionConfigResponse,
push_service_delivery: PushServiceDeliveryConfigResponse,
push_relay: PushRelayConfigResponse,
domain_migration: DomainMigrationConfigResponse,
altcha_captcha: AltchaCaptchaConfigResponse,
experiment_delivery: ExperimentDeliveryConfigResponse,
@@ -695,7 +692,7 @@ const InstancePolicyUpdateSchema = z.object({
export const InstanceConfigUpdateRequest = z.object({
gateway_rollout: GatewayRolloutConfigUpdateRequest.nullish(),
voice_noise_suppression: VoiceNoiseSuppressionConfigUpdateRequest.nullish(),
push_service_delivery: PushServiceDeliveryConfigUpdateRequest.nullish(),
push_relay: PushRelayConfigUpdateRequest.nullish(),
domain_migration: DomainMigrationConfigUpdateRequest.nullish(),
altcha_captcha: AltchaCaptchaConfigUpdateRequest.nullish(),
experiment_delivery: ExperimentDeliveryConfigUpdateRequest.nullish(),
@@ -0,0 +1,123 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
LegacyPushServiceDeliveryWire,
PushRelayConfigSchema,
PushRelayConfigUpdateRequest,
toLegacyPushServiceDeliveryWire,
} from '@fluxer/schema/src/domains/admin/PushRelaySchemas';
import {describe, expect, test} from 'vitest';
const ADMIN_USER_ID = '1500000000000000001';
const ACCEPTED_AT = '2026-09-27T10:11:12.000Z';
describe('push relay consent', () => {
test('reads back as unaccepted by default', () => {
expect(PushRelayConfigSchema.parse({})).toEqual({
relay_consent_accepted: false,
relay_consent_accepted_at: null,
relay_consent_accepted_by: null,
});
});
test('a stored push service delivery row keeps its consent', () => {
expect(
PushRelayConfigSchema.parse({
enabled: true,
config_version: 12,
rollout_basis_points: 10000,
rollout_salt: 'push-service-delivery-v1',
included_user_ids: [],
excluded_user_ids: ['1500000000000000003'],
relay_consent_accepted: true,
relay_consent_accepted_at: ACCEPTED_AT,
relay_consent_accepted_by: ADMIN_USER_ID,
}),
).toEqual({
relay_consent_accepted: true,
relay_consent_accepted_at: ACCEPTED_AT,
relay_consent_accepted_by: ADMIN_USER_ID,
});
});
test('a stored row that predates relay consent reads back as not accepted', () => {
expect(
PushRelayConfigSchema.parse({
enabled: true,
config_version: 4,
rollout_basis_points: 10000,
rollout_salt: 'push-service-delivery-v1',
included_user_ids: [],
excluded_user_ids: [],
}),
).toEqual({
relay_consent_accepted: false,
relay_consent_accepted_at: null,
relay_consent_accepted_by: null,
});
});
test('an accepted consent round-trips', () => {
const accepted = {
relay_consent_accepted: true,
relay_consent_accepted_at: ACCEPTED_AT,
relay_consent_accepted_by: ADMIN_USER_ID,
};
expect(PushRelayConfigSchema.parse(accepted)).toEqual(accepted);
});
test('the update request takes the consent flag on its own', () => {
expect(PushRelayConfigUpdateRequest.parse({relay_consent_accepted: true})).toEqual({
relay_consent_accepted: true,
});
});
test('the update request drops a client-supplied acceptance stamp', () => {
expect(
PushRelayConfigUpdateRequest.parse({
relay_consent_accepted: true,
relay_consent_accepted_at: '2020-01-01T00:00:00.000Z',
relay_consent_accepted_by: ADMIN_USER_ID,
}),
).toEqual({relay_consent_accepted: true});
});
test.each([
{relay_consent_accepted_at: 'yesterday'},
{relay_consent_accepted_at: '2026-09-27'},
{relay_consent_accepted_by: 'not-an-id'},
{relay_consent_accepted: 'yes'},
])('rejects a malformed stored consent: %j', (value) => {
expect(PushRelayConfigSchema.safeParse(value).success).toBe(false);
});
});
describe('legacy push service delivery wire', () => {
test('pins every rollout field to full enrolment and keeps the consent and version', () => {
const wire = toLegacyPushServiceDeliveryWire(
{relay_consent_accepted: true, relay_consent_accepted_at: ACCEPTED_AT, relay_consent_accepted_by: ADMIN_USER_ID},
7,
);
expect(wire).toEqual({
enabled: true,
config_version: 7,
rollout_basis_points: 10000,
rollout_salt: 'push-service-delivery-v1',
included_user_ids: [],
excluded_user_ids: [],
relay_consent_accepted: true,
relay_consent_accepted_at: ACCEPTED_AT,
relay_consent_accepted_by: ADMIN_USER_ID,
});
expect(LegacyPushServiceDeliveryWire.parse(wire)).toEqual(wire);
});
test('rejects a document that would take anyone off the push service', () => {
const wire = toLegacyPushServiceDeliveryWire(PushRelayConfigSchema.parse({}), 0);
expect(LegacyPushServiceDeliveryWire.safeParse({...wire, enabled: false}).success).toBe(false);
expect(LegacyPushServiceDeliveryWire.safeParse({...wire, rollout_basis_points: 5000}).success).toBe(false);
expect(LegacyPushServiceDeliveryWire.safeParse({...wire, excluded_user_ids: ['1500000000000000003']}).success).toBe(
false,
);
});
});
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {z} from 'zod';
const LEGACY_PUSH_SERVICE_DELIVERY_ROLLOUT_BASIS_POINTS = 10000;
const LEGACY_PUSH_SERVICE_DELIVERY_SALT = 'push-service-delivery-v1';
export const PushRelayConfigSchema = z.object({
relay_consent_accepted: z.boolean().default(false),
relay_consent_accepted_at: z.iso.datetime().nullable().default(null),
relay_consent_accepted_by: z
.string()
.regex(/^\d{1,20}$/u)
.nullable()
.default(null),
});
export type PushRelayConfig = z.infer<typeof PushRelayConfigSchema>;
export const PushRelayConfigResponse = PushRelayConfigSchema;
export type PushRelayConfigResponse = z.infer<typeof PushRelayConfigResponse>;
export const PushRelayConfigUpdateRequest = z.object({
relay_consent_accepted: z.boolean().optional(),
});
export type PushRelayConfigUpdateRequest = z.infer<typeof PushRelayConfigUpdateRequest>;
export const LegacyPushServiceDeliveryWire = PushRelayConfigSchema.extend({
enabled: z.literal(true),
config_version: z.number().int().min(0),
rollout_basis_points: z.literal(LEGACY_PUSH_SERVICE_DELIVERY_ROLLOUT_BASIS_POINTS),
rollout_salt: z.literal(LEGACY_PUSH_SERVICE_DELIVERY_SALT),
included_user_ids: z.tuple([]),
excluded_user_ids: z.tuple([]),
});
export type LegacyPushServiceDeliveryWire = z.infer<typeof LegacyPushServiceDeliveryWire>;
export function toLegacyPushServiceDeliveryWire(
config: PushRelayConfig,
configVersion: number,
): LegacyPushServiceDeliveryWire {
return {
enabled: true,
config_version: configVersion,
rollout_basis_points: LEGACY_PUSH_SERVICE_DELIVERY_ROLLOUT_BASIS_POINTS,
rollout_salt: LEGACY_PUSH_SERVICE_DELIVERY_SALT,
included_user_ids: [],
excluded_user_ids: [],
relay_consent_accepted: config.relay_consent_accepted,
relay_consent_accepted_at: config.relay_consent_accepted_at,
relay_consent_accepted_by: config.relay_consent_accepted_by,
};
}
@@ -1,89 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {
DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG,
type PushServiceDeliveryConfig,
PushServiceDeliveryConfigSchema,
PushServiceDeliveryConfigUpdateRequest,
pushServiceDeliveryEnrols,
} from '@fluxer/schema/src/domains/admin/PushServiceDeliverySchemas';
import {describe, expect, test} from 'vitest';
const ADMIN_USER_ID = '1500000000000000001';
const TARGETED_USER_ID = '1500000000000000002';
function createConfig(overrides: Partial<PushServiceDeliveryConfig> = {}): PushServiceDeliveryConfig {
return {
...DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG,
included_user_ids: [],
excluded_user_ids: [],
...overrides,
};
}
describe('push service delivery relay consent', () => {
test('a stored configuration that predates relay consent reads back as not accepted', () => {
expect(
PushServiceDeliveryConfigSchema.parse({
enabled: true,
config_version: 4,
rollout_basis_points: 10000,
rollout_salt: 'push-service-delivery-v1',
included_user_ids: [],
excluded_user_ids: [],
}),
).toMatchObject({
relay_consent_accepted: false,
relay_consent_accepted_at: null,
relay_consent_accepted_by: null,
});
});
test('the defaults export carries the unaccepted consent', () => {
expect(DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG.relay_consent_accepted).toBe(false);
expect(DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG.relay_consent_accepted_at).toBeNull();
expect(DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG.relay_consent_accepted_by).toBeNull();
});
test('an accepted consent round-trips through the stored schema', () => {
const accepted = {
...DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG,
relay_consent_accepted: true,
relay_consent_accepted_at: '2026-09-27T10:11:12.000Z',
relay_consent_accepted_by: ADMIN_USER_ID,
};
expect(PushServiceDeliveryConfigSchema.parse(accepted)).toEqual(accepted);
});
test('the update request takes the consent flag on its own', () => {
expect(PushServiceDeliveryConfigUpdateRequest.parse({relay_consent_accepted: true})).toEqual({
relay_consent_accepted: true,
});
});
test('the update request refuses a client-supplied acceptance stamp', () => {
expect(
PushServiceDeliveryConfigUpdateRequest.parse({
relay_consent_accepted: true,
relay_consent_accepted_at: '2020-01-01T00:00:00.000Z',
relay_consent_accepted_by: ADMIN_USER_ID,
}),
).toEqual({relay_consent_accepted: true});
});
test.each([
{relay_consent_accepted_at: 'yesterday'},
{relay_consent_accepted_at: '2026-09-27'},
{relay_consent_accepted_by: 'not-an-id'},
{relay_consent_accepted: 'yes'},
])('rejects a malformed stored consent: %j', (value) => {
expect(PushServiceDeliveryConfigSchema.safeParse(value).success).toBe(false);
});
test('consent alone enrols nobody and refusing it excludes nobody', () => {
const withConsent = createConfig({enabled: false, relay_consent_accepted: true});
const withoutConsent = createConfig({enabled: true, rollout_basis_points: 10000});
expect(pushServiceDeliveryEnrols(withConsent, TARGETED_USER_ID)).toBe(false);
expect(pushServiceDeliveryEnrols(withoutConsent, TARGETED_USER_ID)).toBe(true);
});
});
@@ -1,63 +0,0 @@
// SPDX-License-Identifier: AGPL-3.0-or-later
import {EXPERIMENT_BUCKET_RESOLUTION, experimentBucket} from '@fluxer/schema/src/domains/experiment/ExperimentBucket';
import {z} from 'zod';
const PUSH_SERVICE_DELIVERY_ROLLOUT_BASIS_POINTS_MAX = EXPERIMENT_BUCKET_RESOLUTION;
const PUSH_SERVICE_DELIVERY_MAX_TARGETED_USERS = 1000;
const DEFAULT_PUSH_SERVICE_DELIVERY_SALT = 'push-service-delivery-v1';
const PUSH_SERVICE_DELIVERY_SALT_PATTERN = /^[\x20-\x7e]+$/u;
const PushServiceDeliveryTargetIdSchema = z.string().regex(/^\d{1,20}$/u);
const PushServiceDeliveryTargetedUserIdsSchema = z
.array(PushServiceDeliveryTargetIdSchema)
.max(PUSH_SERVICE_DELIVERY_MAX_TARGETED_USERS);
const pushServiceDeliveryConfigFields = {
enabled: z.boolean(),
config_version: z.number().int().min(0),
rollout_basis_points: z.number().int().min(0).max(PUSH_SERVICE_DELIVERY_ROLLOUT_BASIS_POINTS_MAX),
rollout_salt: z.string().trim().min(1).max(64).regex(PUSH_SERVICE_DELIVERY_SALT_PATTERN),
included_user_ids: PushServiceDeliveryTargetedUserIdsSchema,
excluded_user_ids: PushServiceDeliveryTargetedUserIdsSchema,
relay_consent_accepted: z.boolean(),
relay_consent_accepted_at: z.iso.datetime().nullable(),
relay_consent_accepted_by: PushServiceDeliveryTargetIdSchema.nullable(),
};
export const PushServiceDeliveryConfigSchema = z.object({
enabled: pushServiceDeliveryConfigFields.enabled.default(false),
config_version: pushServiceDeliveryConfigFields.config_version.default(0),
rollout_basis_points: pushServiceDeliveryConfigFields.rollout_basis_points.default(0),
rollout_salt: pushServiceDeliveryConfigFields.rollout_salt.default(DEFAULT_PUSH_SERVICE_DELIVERY_SALT),
included_user_ids: pushServiceDeliveryConfigFields.included_user_ids.default([]),
excluded_user_ids: pushServiceDeliveryConfigFields.excluded_user_ids.default([]),
relay_consent_accepted: pushServiceDeliveryConfigFields.relay_consent_accepted.default(false),
relay_consent_accepted_at: pushServiceDeliveryConfigFields.relay_consent_accepted_at.default(null),
relay_consent_accepted_by: pushServiceDeliveryConfigFields.relay_consent_accepted_by.default(null),
});
export type PushServiceDeliveryConfig = z.infer<typeof PushServiceDeliveryConfigSchema>;
export const DEFAULT_PUSH_SERVICE_DELIVERY_CONFIG: PushServiceDeliveryConfig = PushServiceDeliveryConfigSchema.parse(
{},
);
export const PushServiceDeliveryConfigUpdateRequest = z
.object(pushServiceDeliveryConfigFields)
.omit({config_version: true, relay_consent_accepted_at: true, relay_consent_accepted_by: true})
.partial();
export type PushServiceDeliveryConfigUpdateRequest = z.infer<typeof PushServiceDeliveryConfigUpdateRequest>;
export const PushServiceDeliveryConfigResponse = PushServiceDeliveryConfigSchema;
export type PushServiceDeliveryConfigResponse = z.infer<typeof PushServiceDeliveryConfigResponse>;
export function pushServiceDeliveryEnrols(config: PushServiceDeliveryConfig, userId: string): boolean {
if (!config.enabled) return false;
if (config.excluded_user_ids.includes(userId)) return false;
if (config.included_user_ids.includes(userId)) return true;
return experimentBucket(userId, config.rollout_salt) < config.rollout_basis_points;
}
@@ -2,7 +2,7 @@
import {RTC_REGION_ID_MAX_LENGTH, RTC_REGION_ID_MIN_LENGTH} from '@fluxer/constants/src/LimitConstants';
import {GatewayRolloutConfigResponse} from '@fluxer/schema/src/domains/admin/GatewayRolloutSchemas';
import {PushServiceDeliveryConfigResponse} from '@fluxer/schema/src/domains/admin/PushServiceDeliverySchemas';
import {LegacyPushServiceDeliveryWire} from '@fluxer/schema/src/domains/admin/PushRelaySchemas';
import {WebAuthnCredentialResponse} from '@fluxer/schema/src/domains/auth/AuthSchemas';
import {ChannelResponse, RtcRegionResponse} from '@fluxer/schema/src/domains/channel/ChannelSchemas';
import {VoiceStateResponse} from '@fluxer/schema/src/domains/gateway/GatewaySchemas';
@@ -529,7 +529,7 @@ export const RpcResponse = z.discriminatedUnion('type', [
.describe('Response type for push service delivery configuration'),
data: z
.object({
config: PushServiceDeliveryConfigResponse.describe('Push service delivery configuration'),
config: LegacyPushServiceDeliveryWire.describe('Push service delivery configuration'),
})
.describe('Push service delivery config result'),
}),