Show per-account delivery status

This commit is contained in:
jjbrunton committed 2026-08-09 16:12:05 +01:00
1 parent 9b86cee9be
commit 22eb32e5bf
14 files changed
+402 -13

No files matched your search

+36
View File
@@ -1,6 +1,37 @@
import { z } from 'zod';
import { ActivityItemSchema } from './activity.js';
export const AccountSendingStateSchema = z.enum([
'ready',
'bot-stopped',
'runtime-stopped',
'runtime-failed',
'login-required',
'matrix-cooldown',
'replies-prioritized',
'pacing',
]);
export const AccountStatusSchema = z.strictObject({
accountId: z.string(),
redditUsername: z.string(),
runtimeState: z.enum(['created', 'starting', 'running', 'stopping', 'stopped', 'failed']),
authenticated: z.boolean(),
sendingState: AccountSendingStateSchema,
messagesThisHour: z.number(),
maxMessagesPerHour: z.number(),
nextMessageAvailableAt: z.number().nullable(),
hourlyResetAt: z.number(),
messagesRemaining: z.number(),
actionableReplies: z.number(),
invitationCooldown: z.strictObject({
until: z.number(),
reason: z.string(),
redditCode: z.string().nullable(),
}).nullable(),
failure: z.string().nullable(),
});
const PerformanceFields = {
totalSent: z.number(),
totalResponses: z.number(),
@@ -27,10 +58,13 @@ export const StatsResponseSchema = z.strictObject({
})),
targetGenders: z.array(z.string()),
recentActivity: z.array(ActivityItemSchema),
accounts: z.array(AccountStatusSchema),
invitationCooldown: z.strictObject({
until: z.number(),
reason: z.string(),
redditCode: z.string().nullable(),
accountId: z.string().optional(),
redditUsername: z.string().optional(),
}).nullable(),
});
@@ -93,5 +127,7 @@ export const AiUsageSummaryResponseSchema = z.strictObject({
});
export type StatsResponse = z.infer<typeof StatsResponseSchema>;
export type AccountStatus = z.infer<typeof AccountStatusSchema>;
export type AccountSendingState = z.infer<typeof AccountSendingStateSchema>;
export type TimersResponse = z.infer<typeof TimersResponseSchema>;
export type AiUsageSummaryResponse = z.infer<typeof AiUsageSummaryResponseSchema>;
@@ -58,6 +58,12 @@ describe('dashboard endpoint contracts', () => {
subreddits: [{ name: 'example', type: 'image' }],
targetGenders: ['female'],
recentActivity: [activity],
accounts: [{
accountId: '@t2_owner:reddit.com', redditUsername: 'owner', runtimeState: 'running',
authenticated: true, sendingState: 'ready', messagesThisHour: 2, maxMessagesPerHour: 8,
nextMessageAvailableAt: null, hourlyResetAt: 1_700_003_600_000, messagesRemaining: 6,
actionableReplies: 0, invitationCooldown: null, failure: null,
}],
invitationCooldown: null,
};
expect(StatsResponseSchema.parse(payload)).toEqual(payload);