Run immediate browsing sessions with enabled votes

This commit is contained in:
jjbrunton committed 2026-08-11 21:59:13 +01:00
1 parent 643c775813
commit 540590f43e
11 files changed
+40 -19

No files matched your search

+5 -3
View File
@@ -31,6 +31,8 @@ export interface AccountBrowsingSimulationServiceOptions {
};
sink: BrowsingDecisionSink;
voter?: BrowsingVoter;
/** Browser dry-run is an absolute no-write boundary, including manual runs. */
dryRun?: boolean;
logger: Logger;
now?: () => number;
random?: () => number;
@@ -55,9 +57,9 @@ export class AccountBrowsingSimulationService {
this.random = options.random ?? Math.random;
}
/** Runs one operator-requested, simulation-only selection without waiting for the schedule. */
/** Runs one operator-requested selection without waiting for the schedule. */
runNow(signal?: AbortSignal): Promise<BrowsingSimulationOutcome> {
return this.tick({ force: true }, signal);
return this.tick({ allowVoting: !this.options.dryRun, force: true }, signal);
}
async tick(
@@ -120,7 +122,7 @@ export class AccountBrowsingSimulationService {
const selected = candidates[Math.floor(this.random() * candidates.length)];
const decision = toDecision(this.options.accountId, selected, 'simulated-upvote', 'Eligible browsing selection', sessionId, now);
await this.options.sink.recordSimulation(decision);
if (settings.autoVoteEnabled && allowVoting && this.options.voter) {
if (settings.autoVoteEnabled && allowVoting && !this.options.dryRun && this.options.voter) {
const result = await this.options.voter.upvote(selected.fullname);
if (result.status === 'submitted') {
this.options.repository.markVoteSubmitted(this.options.accountId, selected.fullname);
@@ -299,6 +299,7 @@ async function buildRuntime(
},
sink: browsingRepository,
voter: commentClient,
dryRun: accountConfig.browser.dryRun,
logger,
onActivity: (decision) => activityLogRepo.insert({
timestamp: decision.decidedAt,
+1 -1
View File
@@ -186,7 +186,7 @@ export const API_OPERATIONS: readonly ApiOperation[] = [
requestSchema: BrowsingSettingsUpdateRequestSchema,
responseSchema: GrowthAccountResponseSchema,
}),
operation('runBrowsingSimulation', 'POST', '/api/growth/{accountId}/browsing/run', 'Run one simulation-only browsing session immediately', ['Growth'], {
operation('runBrowsingSimulation', 'POST', '/api/growth/{accountId}/browsing/run', 'Run one browsing session immediately', ['Growth'], {
access: 'admin',
responseSchema: GrowthAccountResponseSchema,
}),
+1 -1
View File
@@ -107,7 +107,7 @@ export function createGrowthRouter(ctx: WebContext): Router {
} catch (error) {
return res.status(502).json({ error: `Browsing simulation failed: ${errorMessage(error)}` });
}
ctx.broadcaster.push('info', `Browsing simulation run manually for u/${username}; no Reddit vote was submitted`);
ctx.broadcaster.push('info', `Browsing session run manually for u/${username}`);
return res.json({ success: true, account: detail(repo, browsingRepo, accountId, username) });
});