refactor: squash branch changes

This commit is contained in:
Hampus Kraft
2026-02-21 07:15:46 +00:00
parent c2b69be17d
commit d90464c381
153 changed files with 6598 additions and 4444 deletions

View File

@@ -27,7 +27,7 @@ import {ScheduledMessage} from '@fluxer/api/src/models/ScheduledMessage';
import type {User} from '@fluxer/api/src/models/User';
import {withBusinessSpan} from '@fluxer/api/src/telemetry/BusinessSpans';
import type {ScheduledMessageRepository} from '@fluxer/api/src/user/repositories/ScheduledMessageRepository';
import {ManagedTraits} from '@fluxer/constants/src/ManagedTraits';
import {UserFlags} from '@fluxer/constants/src/UserConstants';
import {ValidationErrorCodes} from '@fluxer/constants/src/ValidationErrorCodes';
import {FeatureTemporarilyDisabledError} from '@fluxer/errors/src/domains/core/FeatureTemporarilyDisabledError';
import {InputValidationError} from '@fluxer/errors/src/domains/core/InputValidationError';
@@ -134,7 +134,7 @@ export class ScheduledMessageService {
private async upsertScheduledMessage(params: UpdateScheduleParams): Promise<ScheduledMessage> {
const {user, channelId, data, scheduledLocalAt, timezone} = params;
if (!user.traits.has(ManagedTraits.MESSAGE_SCHEDULING)) {
if ((user.flags & UserFlags.STAFF) === 0n) {
throw new FeatureTemporarilyDisabledError();
}

View File

@@ -19,8 +19,7 @@
import {ensureSessionStarted} from '@fluxer/api/src/message/tests/MessageTestUtils';
import type {ApiTestHarness} from '@fluxer/api/src/test/ApiTestHarness';
import {createBuilder} from '@fluxer/api/src/test/TestRequestBuilder';
import {ManagedTraits} from '@fluxer/constants/src/ManagedTraits';
import {createBuilder, createBuilderWithoutAuth} from '@fluxer/api/src/test/TestRequestBuilder';
import type {MessageResponse} from '@fluxer/schema/src/domains/message/MessageResponseSchemas';
import type {ScheduledMessageResponseSchema} from '@fluxer/schema/src/domains/message/ScheduledMessageSchemas';
import type {z} from 'zod';
@@ -45,14 +44,8 @@ export async function createGuildChannel(
return json as {id: string};
}
export async function enableMessageSchedulingForGuild(harness: ApiTestHarness, guildId: string): Promise<void> {
await createBuilder<void>(harness, '')
.post(`/test/guilds/${guildId}/features`)
.body({
add_features: [ManagedTraits.MESSAGE_SCHEDULING],
})
.expect(200)
.execute();
export async function grantStaffAccess(harness: ApiTestHarness, userId: string): Promise<void> {
await createBuilderWithoutAuth(harness).patch(`/test/users/${userId}/flags`).body({flags: 1}).execute();
}
export async function scheduleMessage(

View File

@@ -20,7 +20,7 @@
import {createTestAccount} from '@fluxer/api/src/auth/tests/AuthTestUtils';
import {
createGuildChannel,
enableMessageSchedulingForGuild,
grantStaffAccess,
scheduleMessage,
} from '@fluxer/api/src/channel/tests/ScheduledMessageTestUtils';
import {createGuild} from '@fluxer/api/src/guild/tests/GuildTestUtils';
@@ -29,7 +29,7 @@ import {type ApiTestHarness, createApiTestHarness} from '@fluxer/api/src/test/Ap
import {createBuilder} from '@fluxer/api/src/test/TestRequestBuilder';
import {beforeAll, beforeEach, describe, expect, it} from 'vitest';
describe('Scheduled message trait gating', () => {
describe('Scheduled message staff gating', () => {
let harness: ApiTestHarness;
beforeAll(async () => {
@@ -40,7 +40,7 @@ describe('Scheduled message trait gating', () => {
await harness.reset();
});
it('rejects scheduling message before trait enabled', async () => {
it('rejects scheduling message before staff flag granted', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'scheduled-flag');
const channel = await createGuildChannel(harness, owner.token, guild.id, 'scheduled-channel');
@@ -56,7 +56,7 @@ describe('Scheduled message trait gating', () => {
.expect(403)
.execute();
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const scheduled = await scheduleMessage(harness, channel.id, owner.token, 'enabled now');
expect(scheduled.id).toBeDefined();

View File

@@ -20,7 +20,7 @@
import {createTestAccount} from '@fluxer/api/src/auth/tests/AuthTestUtils';
import {
createGuildChannel,
enableMessageSchedulingForGuild,
grantStaffAccess,
scheduleMessage,
} from '@fluxer/api/src/channel/tests/ScheduledMessageTestUtils';
import {createGuild} from '@fluxer/api/src/guild/tests/GuildTestUtils';
@@ -49,7 +49,7 @@ describe('Scheduled message validation', () => {
it('rejects scheduling message with past time', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'sched-validation-past');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'test');
await ensureSessionStarted(harness, owner.token);
@@ -76,7 +76,7 @@ describe('Scheduled message validation', () => {
it('rejects scheduling message exceeding 30 days', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'sched-validation-30day');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'test');
await ensureSessionStarted(harness, owner.token);
@@ -103,7 +103,7 @@ describe('Scheduled message validation', () => {
it('rejects scheduling message with invalid timezone', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'sched-validation-tz');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'test');
await ensureSessionStarted(harness, owner.token);
@@ -130,7 +130,7 @@ describe('Scheduled message validation', () => {
it('accepts scheduling message at 30 day boundary', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'sched-validation-boundary');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'test');
const futureTime = new Date(Date.now() + 29 * 24 * 60 * 60 * 1000 + 23 * 60 * 60 * 1000).toISOString();

View File

@@ -21,9 +21,9 @@ import {createTestAccount} from '@fluxer/api/src/auth/tests/AuthTestUtils';
import {
createChannelInvite,
createGuildChannel,
enableMessageSchedulingForGuild,
getChannelMessages,
getScheduledMessage,
grantStaffAccess,
joinGuild,
messageFromAuthorContains,
removeGuildMember,
@@ -49,7 +49,7 @@ describe('Scheduled message worker lifecycle', () => {
it('delivers scheduled message when permissions remain', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'scheduled-messages');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'scheduled');
const content = 'scheduled message goes through';
@@ -67,7 +67,7 @@ describe('Scheduled message worker lifecycle', () => {
it('reschedules pending message before worker execution', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'scheduled-messages');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'scheduled');
const content = 'scheduled message initial content';
@@ -106,7 +106,7 @@ describe('Scheduled message worker lifecycle', () => {
const owner = await createTestAccount(harness);
const member = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'scheduled-messages');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, member.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'scheduled');
const invite = await createChannelInvite(harness, owner.token, channel.id);

View File

@@ -21,8 +21,8 @@ import {createTestAccount} from '@fluxer/api/src/auth/tests/AuthTestUtils';
import {
createChannelInvite,
createGuildChannel,
enableMessageSchedulingForGuild,
getScheduledMessages,
grantStaffAccess,
joinGuild,
removeGuildMember,
scheduleMessage,
@@ -47,7 +47,7 @@ describe('Scheduled messages list invalid entry', () => {
const owner = await createTestAccount(harness);
const member = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'scheduled-invalid');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, member.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'scheduled-invalid');
const invite = await createChannelInvite(harness, owner.token, channel.id);

View File

@@ -21,8 +21,8 @@ import {createTestAccount} from '@fluxer/api/src/auth/tests/AuthTestUtils';
import {
cancelScheduledMessage,
createGuildChannel,
enableMessageSchedulingForGuild,
getScheduledMessages,
grantStaffAccess,
scheduleMessage,
} from '@fluxer/api/src/channel/tests/ScheduledMessageTestUtils';
import {createGuild} from '@fluxer/api/src/guild/tests/GuildTestUtils';
@@ -43,7 +43,7 @@ describe('Scheduled messages list lifecycle', () => {
it('lists scheduled messages and removes after cancel', async () => {
const owner = await createTestAccount(harness);
const guild = await createGuild(harness, owner.token, 'scheduled-list');
await enableMessageSchedulingForGuild(harness, guild.id);
await grantStaffAccess(harness, owner.userId);
const channel = await createGuildChannel(harness, owner.token, guild.id, 'scheduled-list');
const content = 'list scheduled';