NOTE: THIS COULD BE DONE IN TYPESCRIPT OR RUST
BECAUSE THIS SHOULD BE IMPLEMENTED AS A SEPARATE MICROSERVICE
Ingest GitHub Issues into Backend Database
Reference: issue #74
-
Scope
- Ingest issues from specified GitHub repositories via REST API.
- Persist issues with metadata, assignees, labels/tags, points, reward-processing flags.
- Idempotent upserts based on a composite key to avoid duplicates across repos.
- Exclude pagination, retry/backoff, and endpoint auth from this ticket.
-
Data Model
github_issues
- Primary Key:
(repo_id BIGINT, github_issue_id BIGINT) — composite PK to avoid duplicates across repos.
repo TEXT (org/repo)
repo_id BIGINT (GitHub repository ID)
github_issue_id BIGINT (GitHub global issue ID)
number INT (repo-scoped issue number)
title TEXT
state TEXT ENUM-like: open | closed
labels JSONB (or normalized later)
points INT (derived; default 0)
assignee_logins JSONB (or normalized later)
html_url TEXT
created_at TIMESTAMPTZ
closed_at TIMESTAMPTZ NULL
rewarded BOOL DEFAULT false
distribution_id TEXT NULL
updated_at TIMESTAMPTZ
- (Optional normalization, out of scope now)
github_issue_assignees(issue_repo_id BIGINT, issue_github_issue_id BIGINT, assignee_login TEXT)
-
Endpoint (Auth deferred)
POST /admin/github/sync
- Body:
{ repos: string[] } (each org/repo), optional { since: string ISO }
- Performs ingestion for provided repos (or configured defaults if not provided).
- Idempotent upsert keyed by
(repo_id, github_issue_id).
-
Logic Notes
- Ignore PRs (or store with
is_pull_request=true but do not compute points) — choose ignore for simplicity.
- Derive
points from label patterns like points:3; default 0 if none.
- Persist assignee GitHub logins.
- Closed issues are candidates for rewards; do not set
rewarded in this sync.
- Minimal happy-path sync; pagination and rate limit handling are out of scope for this ticket.
-
Validation
- Ensure
(repo_id, github_issue_id) drives idempotency (upsert).
- Normalize label names to lower-case.
-
Acceptance Criteria
- DB schema created with composite primary key
(repo_id, github_issue_id).
POST /admin/github/sync ingests issues for the specified repos and upserts idempotently.
- Points derived from labels; assignees and states persisted.
- Running sync twice yields no duplicates.
- Tests: transformation (labels → points), idempotent upsert, closed issue reflected.
Follow-up Task: Secure the Sync Endpoint
Reference: issue #74
-
Goal
- Add authentication/authorization to
POST /admin/github/sync.
-
Scope
- Require admin-only access (reuse existing auth middleware/policy).
- Accept an API key or JWT consistent with current backend auth.
- Return
401/403 on unauthenticated/unauthorized.
-
Acceptance Criteria
- Unauthorized requests to
/admin/github/sync are rejected.
- Authorized admin can trigger sync successfully.
- Tests for auth success/failure paths.
NOTE: THIS COULD BE DONE IN TYPESCRIPT OR RUST
BECAUSE THIS SHOULD BE IMPLEMENTED AS A SEPARATE MICROSERVICE
Ingest GitHub Issues into Backend Database
Reference: issue #74
Scope
Data Model
github_issues(repo_id BIGINT, github_issue_id BIGINT)— composite PK to avoid duplicates across repos.repoTEXT (org/repo)repo_idBIGINT (GitHub repository ID)github_issue_idBIGINT (GitHub global issue ID)numberINT (repo-scoped issue number)titleTEXTstateTEXT ENUM-like:open|closedlabelsJSONB (or normalized later)pointsINT (derived; default 0)assignee_loginsJSONB (or normalized later)html_urlTEXTcreated_atTIMESTAMPTZclosed_atTIMESTAMPTZ NULLrewardedBOOL DEFAULT falsedistribution_idTEXT NULLupdated_atTIMESTAMPTZgithub_issue_assignees(issue_repo_id BIGINT, issue_github_issue_id BIGINT, assignee_login TEXT)Endpoint (Auth deferred)
POST /admin/github/sync{ repos: string[] }(eachorg/repo), optional{ since: string ISO }(repo_id, github_issue_id).Logic Notes
is_pull_request=truebut do not compute points) — choose ignore for simplicity.pointsfrom label patterns likepoints:3; default0if none.rewardedin this sync.Validation
(repo_id, github_issue_id)drives idempotency (upsert).Acceptance Criteria
(repo_id, github_issue_id).POST /admin/github/syncingests issues for the specified repos and upserts idempotently.Follow-up Task: Secure the Sync Endpoint
Reference: issue #74
Goal
POST /admin/github/sync.Scope
401/403on unauthenticated/unauthorized.Acceptance Criteria
/admin/github/syncare rejected.