Skip to content

fix(ads-simulator): address code review — CLI validation, constants, …#143

Merged
gamblecodezcom merged 1 commit into
mainfrom
claude/telegram-ads-simulator-ONM5x
Mar 7, 2026
Merged

fix(ads-simulator): address code review — CLI validation, constants, …#143
gamblecodezcom merged 1 commit into
mainfrom
claude/telegram-ads-simulator-ONM5x

Conversation

@gamblecodezcom
Copy link
Copy Markdown
Owner

@gamblecodezcom gamblecodezcom commented Mar 7, 2026

…time-window aggregation

Three issues from code review resolved:

  1. CLI argument validation (brittle --output handling)

    • Add USAGE string and die() helper; process.exit(1) on all error paths
    • Detect --output as last arg with no path
    • Detect --output followed by another flag (e.g. --output --summary-only)
    • Detect mutually exclusive --summary-only + --json-only
    • Detect --output combined with --summary-only or --json-only
    • Reject unknown flags with clear error message
  2. Centralize magic numbers as named constants

    • IMPRESSIONS_BASE (10000), OPT_ITERATIONS (3), TOP_COMBOS (20), TOP_AD_COUNT (3)
    • All formerly hardcoded values now reference these constants
    • simulation_config now exposes top_combos_per_ad, optimization_iterations, top_ads_selected so the JSON output is self-documenting
    • Log progress strings use RAW_ADS.length and OPT_ITERATIONS, not literals
    • note string in simulation_config computed dynamically from dimension lengths
  3. selectTopAds time-window aggregation (arbitrary first element)

    • Now iterates ALL TOP_COMBOS combinations (not just top-5) per channel
    • Accumulates ROI-weighted counts for each time_bucket and day_of_week
    • Selects the highest ROI-weighted time bucket as the recommended window
    • Selects top-3 days by accumulated ROI weight
    • reason field now reports the count of combinations used in the aggregation

https://claude.ai/code/session_01QSkvVSYsiNQ9udQ3fvVopJ

Summary by Sourcery

Improve the Telegram ads simulator CLI robustness, centralize simulation tuning constants, and refine top-ad time-window aggregation logic for more accurate recommendations and self-documenting output.

New Features:

  • Add a CLI usage banner and structured argument validation for output and mode flags.
  • Expose simulation tuning parameters in the JSON output via a richer simulation_config block.

Bug Fixes:

  • Fix selectTopAds time-window aggregation to consider all top combinations per channel and choose time buckets and days based on ROI-weighted counts rather than an arbitrary first element.

Enhancements:

  • Centralize previously hardcoded simulation magic numbers into named constants used across bidding, optimization, and selection logic.
  • Make logging and summary messaging dynamically reflect the number of ads, combinations, and optimization iterations instead of fixed literals.
  • Adjust default JSON and summary output formatting to reduce duplication and ensure consistent combined output when writing to files or stdout.

Summary by CodeRabbit

  • New Features

    • Configurable simulation parameters for iterations, ad counts, and combination selections.
    • Expanded output metadata including optimization details and dynamic configuration references.
    • Improved default output formatting combining JSON and summary in a single block.
  • Bug Fixes

    • Enhanced CLI argument validation with strict error checking and better failure messaging.
    • Strengthened ad text optimization with improved constraint handling across iterations.

…time-window aggregation

Three issues from code review resolved:

1. CLI argument validation (brittle --output handling)
   - Add USAGE string and die() helper; process.exit(1) on all error paths
   - Detect --output as last arg with no path
   - Detect --output followed by another flag (e.g. --output --summary-only)
   - Detect mutually exclusive --summary-only + --json-only
   - Detect --output combined with --summary-only or --json-only
   - Reject unknown flags with clear error message

2. Centralize magic numbers as named constants
   - IMPRESSIONS_BASE (10000), OPT_ITERATIONS (3), TOP_COMBOS (20), TOP_AD_COUNT (3)
   - All formerly hardcoded values now reference these constants
   - simulation_config now exposes top_combos_per_ad, optimization_iterations,
     top_ads_selected so the JSON output is self-documenting
   - Log progress strings use RAW_ADS.length and OPT_ITERATIONS, not literals
   - note string in simulation_config computed dynamically from dimension lengths

3. selectTopAds time-window aggregation (arbitrary first element)
   - Now iterates ALL TOP_COMBOS combinations (not just top-5) per channel
   - Accumulates ROI-weighted counts for each time_bucket and day_of_week
   - Selects the highest ROI-weighted time bucket as the recommended window
   - Selects top-3 days by accumulated ROI weight
   - reason field now reports the count of combinations used in the aggregation

https://claude.ai/code/session_01QSkvVSYsiNQ9udQ3fvVopJ
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Mar 7, 2026

Reviewer's Guide

Refactors the Telegram ads simulator script to add robust CLI argument validation, centralize simulation tuning constants, and improve the selection of top ads by aggregating time-window performance across all top combinations instead of an arbitrary subset.

File-Level Changes

Change Details Files
Add robust CLI argument parsing/validation and usage guidance for the simulator CLI.
  • Introduce a USAGE help string and a die() helper that prints errors plus usage and exits with status 1.
  • Validate mutually exclusive flags --summary-only and --json-only, and reject invalid --output usages (missing path or followed by another flag).
  • Disallow combining --output with --summary-only or --json-only and reject unknown flags with clear error messages.
  • Reorganize main() into explicit argument parsing, simulation, and output phases while preserving behavior for valid flag combinations.
scripts/telegram-ads-simulator.js
Centralize simulation tuning parameters and derived configuration into named constants and JSON output metadata.
  • Introduce IMPRESSIONS_BASE, OPT_ITERATIONS, TOP_COMBOS, and TOP_AD_COUNT constants and replace prior hardcoded literals throughout the simulation pipeline.
  • Make bidSensitivity, optimization loop, top-ad selection, and progress logs reference these constants instead of magic numbers.
  • Enhance simulation_config JSON to expose impressions_per_simulation, top_combos_per_ad, optimization_iterations, top_ads_selected, and a dynamically computed note based on TOP_COMBOS and total combination count.
  • Update summary generation and logging to use RAW_ADS.length and OPT_ITERATIONS, TOP_AD_COUNT rather than fixed values like 30, 3, or 20.
scripts/telegram-ads-simulator.js
Improve selectTopAds time-window aggregation by using ROI-weighted counts across all top combinations per channel.
  • Replace prior logic that used only the first time bucket and all days from the top-5 combinations with an aggregation over all by_time_day_channel_persona entries.
  • For each channel, accumulate ROI_index weights per time_bucket and per day_of_week, then select the single highest-weighted time bucket and top-3 days.
  • Include the number of contributing combinations in the reason string for each best_time_window recommendation.
  • Ensure final_text and metrics reference the last optimization iteration dynamically via OPT_ITERATIONS instead of a hardcoded index.
scripts/telegram-ads-simulator.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gamblecodezcom gamblecodezcom merged commit 3d57bf0 into main Mar 7, 2026
4 of 5 checks passed
@gamblecodezcom gamblecodezcom deleted the claude/telegram-ads-simulator-ONM5x branch March 7, 2026 06:46
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 7, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9669b8f5-ab75-4b50-81dc-00806a394e8e

📥 Commits

Reviewing files that changed from the base of the PR and between 599565b and 9f406c0.

📒 Files selected for processing (1)
  • scripts/telegram-ads-simulator.js

📝 Walkthrough

Walkthrough

This PR refactors scripts/telegram-ads-simulator.js to replace hard-coded values with configurable constants (TOP_COMBOS, OPT_ITERATIONS, TOP_AD_COUNT, IMPRESSIONS_BASE, etc.). CLI argument handling is strengthened with validation and usage guidance. Simulation, optimization, and selection logic now dynamically uses parameterized values, while output generation is expanded with computed metadata reflecting the configurable workflow.

Changes

Cohort / File(s) Summary
Configuration & Parameterization
scripts/telegram-ads-simulator.js
Introduced configurable constants (TOP_COMBOS, OPT_ITERATIONS, TOP_AD_COUNT, IMPRESSIONS_BASE, MAX_LENGTH) replacing hard-coded values; wired them into validation, simulation iteration counts, top selection logic, and output metadata.
CLI Argument Handling & Validation
scripts/telegram-ads-simulator.js
Enhanced argument parsing with fast-fail checks, usage text, mutual exclusivity validation, and strict argument format enforcement.
Simulation & Optimization Logic
scripts/telegram-ads-simulator.js
Modified iteration loop logic to use OPT_ITERATIONS parameter; adjusted validation count to derive from input data; updated step logs to display dynamic values; enhanced top combinations selection from hardcoded top-5 to all TOP_COMBOS with ROI-weighted aggregation for time buckets and channels.
Selection & Output Generation
scripts/telegram-ads-simulator.js
Updated selectTopAds indexing to use OPT_ITERATIONS - 1 instead of hard-coded values; expanded output metadata to include top_combos_per_ad, optimization_iterations, top_ads_selected; modified default stdout formatting to combined JSON + summary block; ensured both are written when --output flag used.
Text Optimization Constraints & Robustness
scripts/telegram-ads-simulator.js
Added MAX_LENGTH constraints to ad text optimization iterations with compliance enforcement; adjusted ROI boosting calculations to reflect multi-iteration lifting behavior.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 Constants bloom where hard-code grew,
Configurable counts make algorithms new,
From CLI whispers to output refined,
The simulator flexes—now parameterized! 🎯
With robust constraints and ROI in sight,
The ads shall optimize with all its might! ✨

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/telegram-ads-simulator-ONM5x

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="scripts/telegram-ads-simulator.js" line_range="39-48" />
<code_context>
+
+// Simulation tuning — change here to adjust the whole simulation
+const IMPRESSIONS_BASE = 10000; // Baseline impressions per ad run at bid=1.0
+const OPT_ITERATIONS   = 3;    // Number of copy-optimization iterations to run
+const TOP_COMBOS       = 20;   // Top combinations stored per ad in by_time_day_channel_persona
+const TOP_AD_COUNT     = 3;    // Number of top ads to select and report
</code_context>
<issue_to_address>
**issue:** Guard against OPT_ITERATIONS being set to 0 or a negative value.

This logic relies on OPT_ITERATIONS being ≥ 1: you create `optimized_versions` with `Array.from({ length: OPT_ITERATIONS })` and later access `result.optimized_versions[OPT_ITERATIONS - 1]`. If OPT_ITERATIONS is ever set to 0 or negative, `optimized_versions` will be empty and `selectTopAds` will hit `undefined.metrics` at runtime. Consider either validating OPT_ITERATIONS (e.g., fail fast if < 1) or handling an empty `optimized_versions` array when selecting top ads.
</issue_to_address>

### Comment 2
<location path="scripts/telegram-ads-simulator.js" line_range="950-958" />
<code_context>
+  if (outputFile && (summaryOnly || jsonOnly)) {
+    die('--output cannot be combined with --summary-only or --json-only.');
+  }
+  const KNOWN_FLAGS = new Set(['--output', '--summary-only', '--json-only']);
+  for (const arg of args) {
+    if (arg.startsWith('--') && !KNOWN_FLAGS.has(arg)) {
+      die(`Unknown flag "${arg}".`);
</code_context>
<issue_to_address>
**suggestion:** Consider allowing a help flag instead of treating it as an unknown option.

Because of the strict `KNOWN_FLAGS` check, `--help` / `-h` will currently be rejected with "Unknown flag" even though you already define `USAGE`. It would be better to special-case these flags to print `USAGE` and exit 0 instead of treating them as invalid.

```suggestion
  if (outputFile && (summaryOnly || jsonOnly)) {
    die('--output cannot be combined with --summary-only or --json-only.');
  }
  const KNOWN_FLAGS = new Set(['--output', '--summary-only', '--json-only', '--help']);

  for (const arg of args) {
    if (arg === '--help' || arg === '-h') {
      console.log(USAGE);
      process.exit(0);
    }
    if (arg.startsWith('--') && !KNOWN_FLAGS.has(arg)) {
      die(`Unknown flag "${arg}".`);
    }
  }
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +39 to +48
const OPT_ITERATIONS = 3; // Number of copy-optimization iterations to run
const TOP_COMBOS = 20; // Top combinations stored per ad in by_time_day_channel_persona
const TOP_AD_COUNT = 3; // Number of top ads to select and report

const USAGE = [
'Usage: node telegram-ads-simulator.js [options]',
'',
'Options:',
' --output <path> Write full JSON + summary to <path>; print summary to stdout.',
' --summary-only Print only the human-readable plain-text summary.',
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Guard against OPT_ITERATIONS being set to 0 or a negative value.

This logic relies on OPT_ITERATIONS being ≥ 1: you create optimized_versions with Array.from({ length: OPT_ITERATIONS }) and later access result.optimized_versions[OPT_ITERATIONS - 1]. If OPT_ITERATIONS is ever set to 0 or negative, optimized_versions will be empty and selectTopAds will hit undefined.metrics at runtime. Consider either validating OPT_ITERATIONS (e.g., fail fast if < 1) or handling an empty optimized_versions array when selecting top ads.

Comment on lines +950 to +958
if (outputFile && (summaryOnly || jsonOnly)) {
die('--output cannot be combined with --summary-only or --json-only.');
}
const KNOWN_FLAGS = new Set(['--output', '--summary-only', '--json-only']);
for (const arg of args) {
if (arg.startsWith('--') && !KNOWN_FLAGS.has(arg)) {
die(`Unknown flag "${arg}".`);
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider allowing a help flag instead of treating it as an unknown option.

Because of the strict KNOWN_FLAGS check, --help / -h will currently be rejected with "Unknown flag" even though you already define USAGE. It would be better to special-case these flags to print USAGE and exit 0 instead of treating them as invalid.

Suggested change
if (outputFile && (summaryOnly || jsonOnly)) {
die('--output cannot be combined with --summary-only or --json-only.');
}
const KNOWN_FLAGS = new Set(['--output', '--summary-only', '--json-only']);
for (const arg of args) {
if (arg.startsWith('--') && !KNOWN_FLAGS.has(arg)) {
die(`Unknown flag "${arg}".`);
}
}
if (outputFile && (summaryOnly || jsonOnly)) {
die('--output cannot be combined with --summary-only or --json-only.');
}
const KNOWN_FLAGS = new Set(['--output', '--summary-only', '--json-only', '--help']);
for (const arg of args) {
if (arg === '--help' || arg === '-h') {
console.log(USAGE);
process.exit(0);
}
if (arg.startsWith('--') && !KNOWN_FLAGS.has(arg)) {
die(`Unknown flag "${arg}".`);
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants