Skip to content

RED-109: AI-powered subreddit analyzer redesign#185

Merged
aegloist merged 2 commits into
mainfrom
feature/RED-109-analyzer-redesign
Mar 18, 2026
Merged

RED-109: AI-powered subreddit analyzer redesign#185
aegloist merged 2 commits into
mainfrom
feature/RED-109-analyzer-redesign

Conversation

@aegloist
Copy link
Copy Markdown
Owner

Summary

Complete redesign of the subreddit analyzer using AI to parse and categorize rules.

Before: Raw rule text dump, no interpretation, confusing stats

After:

  • Verdict banner (green/yellow/red) — instant go/no-go decision
  • Deal-breaker chips — min karma, flair, link restrictions at a glance
  • Rules categorized into Promotion, Content, Community, Moderation with severity colors
  • Posting strategy with specific do/don't tips per subreddit
  • Related subreddit suggestions
  • Community stats with formatted numbers

Uses gpt-5.2 for structured rule analysis ($0.88/$7 per 1M tokens).

Test Plan

  • All 467 tests pass
  • TypeScript clean

🤖 Generated with Claude Code

… and strategy

- New analyzeSubredditRules() function using gpt-5.2 for structured analysis
- Verdict banner: green (Promotion Friendly), yellow (Caution), red (Not Recommended)
- Deal-breaker chips: min karma, account age, flair, link restrictions
- Rules categorized: Promotion, Content, Community, Moderation with severity colors
- Posting strategy with do/don't tips specific to each subreddit
- Related subreddits suggestions
- Community stats with formatted numbers
- Added subreddit-analysis AI feature type
- Updated tests with analyzeRules mock

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 18, 2026 19:14
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 18, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openfast Ready Ready Preview, Comment Mar 18, 2026 7:23pm

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Redesigns the public “subreddit analyzer” tool to produce an AI-generated, structured interpretation of subreddit rules (verdict, deal-breakers, categorized rules, strategy, similar subs) and updates the API + UI to serve/render this new analysis.

Changes:

  • Add analyzeSubredditRules (LLM-backed) to convert raw rules + metadata into a structured SubredditAnalysis.
  • Update /api/tools/subreddit-analyzer to return analysis alongside rules/time windows and wire it into the public page UI.
  • Extend AI feature routing to support "subreddit-analysis" model selection and update unit tests accordingly.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/unit/api/subredditAnalyzerToolRoute.test.ts Mocks analyzeSubredditRules and asserts analysis.verdict is returned for both live and cached paths.
src/lib/subreddit/analyzeRules.ts New LLM analyzer module returning structured rule analysis from OpenAI output.
src/lib/ai/openaiClient.ts Adds "subreddit-analysis" as a feature with default model + env override.
src/app/api/tools/subreddit-analyzer/route.ts Calls analyzer and returns analysis in API response; refactors cached/live data paths.
src/app/(public)/tools/subreddit-analyzer/page.tsx UI overhaul to display verdict banner, requirements chips, categorized rules, strategy, similar subs, and stats.
Comments suppressed due to low confidence (1)

src/app/api/tools/subreddit-analyzer/route.ts:57

  • The Prisma query includes policy and rules, but the handler doesn't read either of those objects anymore. Either remove these includes to avoid extra DB work, or (preferably) use the latest rules record to populate subredditData.rules for the cached path.
    include: {
      policy: true,
      rules: { orderBy: { fetchedAt: "desc" }, take: 1 },
      timeSlots: { orderBy: { score: "desc" }, take: 5 },

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +86 to +90
nsfw: subreddit.nsfw,
isRestricted: subreddit.isRestricted,
isQuarantined: subreddit.isQuarantined,
rules: [],
topTimeWindows: subreddit.timeSlots,
latestRulesFetchedAt: subreddit.rules[0]?.fetchedAt ?? null,
staleHours,
source: "database",
meta: {
limit: rl.limit,
remaining: rl.remaining,
resetAfterSeconds: rl.resetAfterSeconds,
},
});
}

// No DB record — fetch inline via .json endpoints (works without Reddit API)
let fetched;
try {
fetched = await fetchSubredditDataWithCache(name);
} catch {
return NextResponse.json(
{
error: "Could not fetch subreddit data. Check the name and try again.",
code: "FETCH_FAILED",
},
{ status: 502 },
);
}
};
Comment thread src/lib/subreddit/analyzeRules.ts Outdated
Comment on lines +114 to +122
// Extract JSON from response (may have markdown wrapping)
const jsonStart = raw.indexOf("{");
const jsonEnd = raw.lastIndexOf("}");
if (jsonStart < 0 || jsonEnd < 0) return null;

try {
const parsed = JSON.parse(
raw.slice(jsonStart, jsonEnd + 1),
) as SubredditAnalysis;
Comment thread src/lib/subreddit/analyzeRules.ts Outdated
Comment on lines +124 to +128
// Validate required fields
if (!parsed.verdict || !parsed.verdictLabel || !parsed.rules) return null;

// Clamp arrays
parsed.rules = parsed.rules.slice(0, 10);
Comment on lines +127 to +136
// Run AI analysis on the rules
const analysis = await analyzeSubredditRules({
subredditName: subredditData.name,
subscribers: subredditData.subscribers,
description: subredditData.description,
rules: subredditData.rules,
isRestricted: subredditData.isRestricted,
isQuarantined: subredditData.isQuarantined,
nsfw: subredditData.nsfw,
}).catch(() => null);
- Cache AI analysis in Redis (12hr TTL) — prevents duplicate AI calls for same subreddit
- Extract rules from DB SubredditRule.rawRules (was sending empty array)
- Skip AI call when no rules available (saves cost)
- Prompt injection defense: sanitize rule text, wrap in delimiters, instruct AI to ignore embedded instructions
- Validate verdict enum (only accept 4 valid values)
- Full runtime validation of AI output (category, severity, string lengths)
- Sanitize all AI output strings with length limits

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aegloist aegloist merged commit b4d0660 into main Mar 18, 2026
4 of 5 checks passed
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