feat: migration-led schema, weighted Groq routing, Reddit RSS-by-default - #15
Merged
Conversation
- Run 'alembic upgrade head' at startup when IS_PROD is false, before seeding. - Remove schema-freeze conditional migrations; keywords and vendor_mappings are now created unconditionally, matching the running models. - Add l5m6n7o8p9q1 to add PEARSONVUE/TRAINING_PROVIDER to the sourcetype enum. - Add m6n7o8p9q0r1 to reconcile create_all-built DBs: create voucher_posts view and make vendor_mappings timestamps timezone-aware. - Align models with migrations: url_pattern as unique index, keyword server defaults, vendor_mapping timestamps. - env.py: escape % in DB URL, import all models, exclude view tables from autogenerate so 'alembic check' is clean. - Add migration-graph tests and startup wiring tests.
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (31)
📝 WalkthroughWalkthroughThe change keeps Reddit RSS collection active when OAuth ingestion is disabled, adds Alembic migrations to startup and schema reconciliation, updates Reddit source seeding, and introduces weighted multi-model Groq routing with exhaustion handling. ChangesReddit ingestion behavior
Migration and schema management
Groq model routing
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant Scheduler
participant RedditCollector
participant RedditClient
participant PublicRSS
Scheduler->>RedditCollector: collect due Reddit source
RedditCollector->>RedditClient: use OAuth API when enabled and configured
RedditClient-->>RedditCollector: return API posts
RedditCollector->>PublicRSS: fetch feeds when OAuth is disabled or unavailable
PublicRSS-->>RedditCollector: return RSS posts
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
29 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This branch consolidates the work done since
maindiverged, landing AI-layer routing, Reddit ingestion policy, source catalog curation, and a complete rewrite of how the database schema is managed (Alembic migrations are now authoritative and run at app startup). Together these make the app boot on a brand-new system with a brand-new DB end-to-end (schema + seed data) with no manual steps.1. AI Layer — weighted Groq model routing (
voucherbot/services/ai/analyzer.py,92acc03)llama-3.1-8b-instant/gpt-oss-120b/llama-3.3-70b-versatilewith weighted routing:openai/gpt-oss-20b(40%),openai/gpt-oss-120b(40%),llama-3.3-70b-versatile(20%), respecting each model's TPM/TPD/RPD quotas._pick_groq_model(exclude=...)picks a model by weight, skipping daily-exhausted ones; failures fall back to the remaining available models.2. Reddit ingestion policy (
db1d383,4339ca8)REDDIT_INGESTION_ENABLED=false(the default) now collects Reddit purely via public RSS feeds and never calls the OAuth API — enforced inRedditCollectorregardless of whether OAuth credentials are configured.REDDITsources when ingestion was disabled (no longer needed — the collector itself handles it).author=None), keeping[deleted]-style noise out of the pipeline.3. Source catalog curation (
4339ca8, docs)O365Certification,mcsa,ccnp,linuxadmin,salesforce,vmware; removedMicrosoftLearn,LinuxCertifications,eFreebies,FREE)._seed_reddit_sourcesnow disables Reddit sources no longer in the active catalog so stale subreddits stop being fetched.4. Database schema management — Alembic migrations are now authoritative (
e990211)This is the largest change. Previously the schema was created by
init_db()/create_allat startup; nowalembic upgrade headruns at startup whenIS_PROD=false(before seeding), and the migration chain fully reproduces the schema the running models define.voucherbot/main.py: non-prod startup runsalembic upgrade head(in a thread) thenbootstrap_data(); prod skips DB setup entirely. Newrun_migrations()helper.g3b9(keywords) now creates the table unconditionally; the redundantj0k1vendor_mappings freeze was removed (its table was already created byh4d5) and the chain rewired.l5m6n7o8p9q1— addsPEARSONVUE/TRAINING_PROVIDERto thesourcetypeenum.m6n7o8p9q0r1— reconcilescreate_all-built DBs: creates thevoucher_postsview and makesvendor_mappings.created_at/updated_attimezone-aware. No-op on fresh DBs.migrations/env.py: escapes%in the DB URL (fixes configparser interpolation crash on percent-encoded passwords), imports every model intoBase.metadata, and adds aninclude_objectfilter so view-backed models are excluded from autogenerate (alembic checkis now clean).vendor_mappings.url_patternas unique index,keywordserver_defaults,vendor_mappingtimestamps.tests/test_migrations.py(new): enforces a single linear migration chain with exactly one head, resolvabledown_revisions, and all model tables registered.5. Test coverage & cleanup
tests/test_main.py,tests/test_bootstrap.py,tests/test_collectors.py,tests/test_analyzer.py).216686f) and mypy-strict fixes (6bac464).Type of Change
Affected Components
http_policy.py)Testing
pytest— all tests pass (355 passed, 15 skipped)ruff check . && ruff format .— cleanMigration
Notes: On a brand-new empty DB,
alembic upgrade headat startup builds the complete schema (tables, enums, indexes,voucher_postsview) automatically. For existingcreate_all-built DBs, runalembic stamp head(or the newm6n7o8p9q0r1reconciliation migration) —alembic checkpasses cleanly after applying.Policy Checklist
If checked, confirm all of the following:
robots.txtcompliance is preserved — the policy layer is not bypassed or disabled.2.0seconds.REDDIT_INGESTION_ENABLED=falsestill collects Reddit via RSS and makes no OAuth calls.httpxoraiohttpcalls exist outside the policy layer.Explanation: Reddit collection now strictly uses public RSS feeds when
REDDIT_INGESTION_ENABLED=false; the OAuth path is only reachable when explicitly enabled. No policy-layer crawl delays or robots.txt handling were changed.AI Layer Changes
Before / After: Model routing changed from a fixed round-robin batch to weighted 40/40/20 distribution across
gpt-oss-20b/gpt-oss-120b/llama-3.3-70b-versatile, each respecting its TPM/TPD/RPD quota. No prompt or output-schema changes.Additional Notes
No secrets are introduced or changed.
alembic checkverifies the migration chain matches the running models.Summary by CodeRabbit
New Features
Bug Fixes
Documentation