-
Notifications
You must be signed in to change notification settings - Fork 55
Implement postgres migration for contributor and leaderboard #403
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,45 @@ | ||
| # Alembic configuration for SolFoundry backend. | ||
| # | ||
| # Manages database schema migrations for PostgreSQL. | ||
| # The connection URL is read from the DATABASE_URL environment variable | ||
| # at runtime (see alembic/env.py). | ||
|
|
||
| [alembic] | ||
| script_location = migrations/alembic | ||
| prepend_sys_path = . | ||
| # DB URL is overridden at runtime by env.py reading DATABASE_URL env var. | ||
| # Fallback only used when DATABASE_URL is not set. | ||
| sqlalchemy.url = postgresql+asyncpg://localhost/solfoundry | ||
| sqlalchemy.url = postgresql+asyncpg://postgres:postgres@localhost/solfoundry | ||
|
|
||
| [loggers] | ||
| keys = root,sqlalchemy,alembic | ||
|
|
||
| [handlers] | ||
| keys = console | ||
|
|
||
| [formatters] | ||
| keys = generic | ||
|
|
||
| [logger_root] | ||
| level = WARN | ||
| handlers = console | ||
|
|
||
| [logger_sqlalchemy] | ||
| level = WARN | ||
| handlers = | ||
| qualname = sqlalchemy.engine | ||
|
|
||
| [logger_alembic] | ||
| level = INFO | ||
| handlers = | ||
| qualname = alembic | ||
|
|
||
| [handler_console] | ||
| class = StreamHandler | ||
| args = (sys.stderr,) | ||
| level = NOTSET | ||
| formatter = generic | ||
|
|
||
| [formatter_generic] | ||
| format = %(levelname)-5.5s [%(name)s] %(message)s | ||
| datefmt = %H:%M:%S |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,13 +49,24 @@ async def health_check() -> dict: | |
| db_status = await _check_database() | ||
| redis_status = await _check_redis() | ||
|
|
||
| # Get counters for sync status | ||
| from app.services import contributor_service | ||
| from app.services.bounty_service import _bounty_store | ||
| from app.services.github_sync import get_last_sync | ||
|
|
||
| contributor_count = await contributor_service.count_contributors() | ||
| last_sync = get_last_sync() | ||
|
Comment on lines
+52
to
+58
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Health check may fail entirely if The Additionally, accessing Proposed fix for resilient health metrics # Get counters for sync status
from app.services import contributor_service
from app.services.bounty_service import _bounty_store
from app.services.github_sync import get_last_sync
- contributor_count = await contributor_service.count_contributors()
+ try:
+ contributor_count = await contributor_service.count_contributors()
+ except Exception:
+ logger.warning("Health check: failed to count contributors")
+ contributor_count = -1 # Indicate unavailable
+
last_sync = get_last_sync()🤖 Prompt for AI Agents |
||
|
|
||
| is_healthy = db_status == "connected" and redis_status == "connected" | ||
|
|
||
| return { | ||
| "status": "healthy" if is_healthy else "degraded", | ||
| "version": "1.0.0", | ||
| "uptime_seconds": round(time.monotonic() - START_TIME), | ||
| "timestamp": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), | ||
| "bounties": len(_bounty_store), | ||
| "contributors": contributor_count, | ||
| "last_sync": last_sync.isoformat() if last_sync else None, | ||
| "services": { | ||
| "database": db_status, | ||
| "redis": redis_status, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comma-separated filters are forwarded without normalization.
Lines 65-66 split raw query strings but do not trim whitespace or drop empty tokens. Requests like
?skills=python, rust,become["python", " rust", ""], which flows straight into the DB filters and can suppress otherwise valid matches. As per coding guidelines,backend/**: Analyze thoroughly: Input validation and SQL injection vectors.🤖 Prompt for AI Agents