MVP Issue Audit & Gap Analysis
Generated 2026-03-08 — Based on codebase analysis ⚠️ Could not access GitHub Issues API (no
ghCLI / no token). Known issues referenced from task context only.
Known Open/Completed Issues (from task context)
| # | Title | Status | MVP Step |
|---|---|---|---|
| #61 | GitHub OAuth App Setup + E2E Auth Flow | ✅ Done | MVP #1 |
| #62 | Repository Analysis Pipeline E2E | ✅ Done | MVP #2 |
| #22 | Webhooks | ✅ Done | Bonus |
| #23 | Test Triggers | ✅ Done | Bonus |
| #55 | API Tokens | ✅ Done | Bonus |
MVP #1: GitHub OAuth + E2E Auth Flow — ✅ DONE
Code confirms: better-auth with GitHub social provider, token storage in accounts table, checkConnection endpoint with expiry detection. No new issues needed.
MVP #2: Repository Analysis Pipeline E2E — ✅ DONE
Code confirms: EnhancedRepositoryAnalyzer with 5 plugins (code-structure, config-analysis, dependency-analysis, staging-environment, test-analysis), stored in JSONB via projectAnalyses table. No new issues needed.
MVP #3: Frontend Analysis Results Display 🟡
What exists:
AnalysisPanel— trigger button, loading spinner, error display, results renderingAnalysisResults— summary cards (files/languages/errors/warnings), tech stack badges, collapsible plugin sections with metrics + issues, dependency listAnalysisLoadingSkeleton— exists but not used inAnalysisPanel(uses simple Loader2 spinner instead)AnalysisEmptyState/AnalysisErrorState— exist but not used inAnalysisPanel(inline equivalents used instead)
🟥 GAPS — Draft Issues:
Issue A: Use dedicated AnalysisLoadingSkeleton component in AnalysisPanel
Problem: AnalysisPanel uses a simple <Loader2Icon> spinner. The richer AnalysisLoadingSkeleton component exists in analysis-results.tsx but isn't imported.
Acceptance Criteria:
- Replace inline loading spinner in
AnalysisPanelwithAnalysisLoadingSkeleton - Skeleton matches the layout of actual results (4 stat cards, plugin sections)
Issue B: Use AnalysisEmptyState and AnalysisErrorState in AnalysisPanel
Problem: AnalysisPanel has inline empty/error states. Dedicated components exist but aren't used.
Acceptance Criteria:
- Replace inline empty state with
AnalysisEmptyStatecomponent - Replace inline error state with
AnalysisErrorStatecomponent - Remove duplicated inline markup
Issue C: Add analysis history selector (view previous analyses)
Problem: getAnalyses endpoint returns paginated history, but UI only shows latest. No way to compare or view older runs.
Acceptance Criteria:
- Add dropdown/list showing previous analyses with date + commit SHA
- Clicking selects and displays that analysis
- Current analysis highlighted
Issue D: Display language breakdown as visual chart/bar
Problem: Languages shown as flat badges with counts. No visual weight representation. Acceptance Criteria:
- Show horizontal bar chart or proportional segments for language distribution
- Hover/click shows exact file count and percentage
Issue E: Show analysis duration and metadata
Problem: Analysis panel shows "Last analyzed [date]" but not how long analysis took or which branch/commit. Acceptance Criteria:
- Display branch name and commit SHA (truncated) in results header
- Show analysis duration if available
Issue F: Add dark mode support to analysis results
Problem: Analysis results use hardcoded light-mode colors (text-gray-800, bg-gray-50, bg-red-50, etc.) without dark mode variants.
Acceptance Criteria:
- Add
dark:Tailwind variants to all analysis result components - Test in both light and dark modes
Issue G: Make analysis results responsive for mobile
Problem: Grid layouts use grid-cols-2 md:grid-cols-4 but plugin sections and dependency lists may not be optimally readable on small screens.
Acceptance Criteria:
- Summary cards stack vertically on mobile
- Plugin section issues are readable without horizontal scroll
- Dependency grid adapts to single column on small screens
MVP #4: Error Handling & Edge Cases 🟢
What exists:
- Analysis router catches: repo not found (404), permission denied (403), rate limit (429), generic errors → mapped to TRPCError codes
- GitHub router checks token expiry, returns
needsReconnectionflag LayoutErrorBoundarycomponent for route-level errorsDataBoundarycomponent (exists — generic error boundary)
🟥 GAPS — Draft Issues:
Issue H: Handle GitHub token expiry gracefully in analysis flow
Problem: analysis.analyzeRepository accepts optional githubToken but the frontend doesn't pass the user's stored GitHub token. For private repos, analysis would fail with a confusing error.
Acceptance Criteria:
- Frontend passes user's GitHub access token from accounts table when triggering analysis
- If token is expired, show "Reconnect GitHub" prompt before/instead of error
- If no GitHub account connected, show clear message for private repos
Issue I: Add retry with exponential backoff for rate-limited analysis
Problem: Rate limit errors (429) are caught and shown but there's no automatic retry mechanism. Acceptance Criteria:
- On 429 response, show countdown timer to user ("Retry in X seconds")
- Optional: auto-retry after backoff period
- Show remaining rate limit info if available from GitHub headers
Issue J: Handle large repository analysis timeout
Problem: No timeout configured for analyzeRepository mutation. Large repos could hang indefinitely.
Acceptance Criteria:
- Add configurable timeout (e.g., 120s) to analysis mutation
- Show progress indicators during long analyses (if possible)
- On timeout, show clear error: "Analysis timed out — try a smaller repo or specific branch"
- Consider
maxFiles/maxFileSizeBytesoptions exposed in UI
Issue K: Add toast notifications for analysis success/failure
Problem: Errors shown inline. No toast/notification system for transient feedback. Acceptance Criteria:
- Show success toast when analysis completes ("Analysis complete — X files, Y issues found")
- Show error toast for failures (in addition to inline error)
- Toast auto-dismisses after 5s
Issue L: Add error boundary around AnalysisResults rendering
Problem: If analysis data shape is unexpected (e.g., old format, corrupted JSON), the whole page crashes. No try/catch around rendering.
Acceptance Criteria:
- Wrap
AnalysisResultsin React Error Boundary - Show fallback UI: "Could not display analysis results" with raw JSON toggle
- Log error to console for debugging
Issue M: Validate analysis data shape before rendering
Problem: AnalysisResults accesses analysis.summary, analysis.results, analysis.dependencies without null checks. If any plugin fails silently, the data could be partial.
Acceptance Criteria:
- Add runtime validation (zod or manual) for
StoredAnalysisshape - Gracefully handle missing sections (show "No data" instead of crash)
- Handle case where
resultsarray is empty
Issue N: Handle "repo not found" with specific UI guidance
Problem: 404 errors return "Repository not found: URL" but don't suggest fixes. Acceptance Criteria:
- Show specific error card for repo-not-found
- Suggest: check URL, ensure repo exists, connect GitHub for private repos
- Link to project settings to update repo URL
MVP #5: Demo/Deploy Environment 🟢
What exists:
docker-compose.ymlwith postgres, redis, web, api, ai-servicedocker-compose.dev.yml(dev overrides)- Individual Dockerfiles in
docker/web/,docker/api/,docker/ai-service/ .env.shared.examplewith all required env vars documentedenv.config.tsfor centralized env validation
🟥 GAPS — Draft Issues:
Issue O: Add docker-compose.demo.yml with pre-configured demo settings
Problem: Current docker-compose.yml has placeholder values (your-openai-key, your-github-client-id). No one-command demo setup.
Acceptance Criteria:
- Create
docker-compose.demo.ymlwith sensible defaults for local demo - Include
GITHUB_CLIENT_ID/SECRETsetup instructions inline - Auto-run DB migrations on startup
- Health check endpoints confirm all services are up
Issue P: Add setup script for first-time demo environment
Problem: Getting the demo running requires: copy env file, fill values, generate envs, run docker compose, run migrations. Too many manual steps. Acceptance Criteria:
- Create
scripts/demo-setup.shthat:- Copies
.env.shared.example→.env.shared(if not exists) - Prompts for GitHub OAuth credentials (or uses placeholder)
- Generates secrets (BETTER_AUTH_SECRET, JWT_SECRET)
- Runs
docker compose up -d - Waits for health checks
- Runs DB migrations
- Prints access URLs
- Copies
- Document in README
Issue Q: Add production-ready environment variable validation on startup
Problem: env.config.ts exists but unclear if the app fails fast on missing critical vars (DATABASE_URL, secrets).
Acceptance Criteria:
- App exits with clear error if required env vars are missing
- Distinguish required vs optional vars
- Log which vars are missing (not their values)
Issue R: Document OAuth callback URL configuration for different environments
Problem: .env.shared.example documents localhost callback URL but not how to configure for deployed environments (different domains, HTTPS).
Acceptance Criteria:
- Add
docs/deployment/oauth-setup.mdwith:- Local development URLs
- Docker deployment URLs
- Production deployment URLs (custom domain)
- Common pitfalls (http vs https, trailing slashes)
- Link from README
Issue S: Add health check endpoint to API service
Problem: Docker compose uses service_started for API, not service_healthy. No dedicated health endpoint.
Acceptance Criteria:
- Add
GET /healthendpoint to API that checks DB connectivity - Update
docker-compose.ymlto usecondition: service_healthyfor API - Return
{ status: "ok", db: "connected" }or appropriate error
Other / Phase 2+ / Nice-to-have
These items were found in the codebase but are NOT on the MVP critical path:
- AI Service integration — Docker service exists but appears unused in analysis flow (analysis runs locally via repo-analyzer package). Phase 2.
- Organization management — Full CRUD exists (members, invites, settings). Already built. Phase 2 polish.
- Project settings page — Exists at
$slug/projects/$id/settings.tsx. Phase 2 polish. - Stats/dashboard — Route exists at
$slug/stats.tsx. Phase 2.
Summary: Issues to Create
MVP #3: Frontend Analysis Results Display (7 issues)
| ID | Title | Priority |
|---|---|---|
| A | Use AnalysisLoadingSkeleton in AnalysisPanel | High |
| B | Use AnalysisEmptyState/ErrorState in AnalysisPanel | High |
| C | Add analysis history selector | Medium |
| D | Language breakdown visual chart | Low |
| E | Show analysis duration and metadata | Medium |
| F | Dark mode support for analysis results | Low |
| G | Mobile responsive analysis results | Medium |
MVP #4: Error Handling & Edge Cases (7 issues)
| ID | Title | Priority |
|---|---|---|
| H | Handle GitHub token expiry in analysis flow | High |
| I | Retry with backoff for rate-limited analysis | Medium |
| J | Large repository analysis timeout | High |
| K | Toast notifications for analysis events | Medium |
| L | Error boundary around AnalysisResults | High |
| M | Validate analysis data shape before render | High |
| N | Repo-not-found specific UI guidance | Medium |
MVP #5: Demo/Deploy Environment (5 issues)
| ID | Title | Priority |
|---|---|---|
| O | docker-compose.demo.yml for one-command demo | High |
| P | First-time demo setup script | High |
| Q | Fail-fast env var validation on startup | Medium |
| R | OAuth callback URL docs for environments | Medium |
| S | API health check endpoint | High |
Total: 19 new granular issues identified
Ready-to-Create Issue Commands
# MVP #3: Frontend Analysis Results Display
gh issue create --title "Use AnalysisLoadingSkeleton component in AnalysisPanel" --label "frontend,mvp" --body "Replace inline loading spinner in AnalysisPanel with the existing AnalysisLoadingSkeleton component for a richer loading UX.\n\n## Acceptance Criteria\n- [ ] Import and use AnalysisLoadingSkeleton from analysis-results.tsx\n- [ ] Skeleton layout matches actual results structure (4 stat cards, plugin sections)"
gh issue create --title "Use AnalysisEmptyState and AnalysisErrorState in AnalysisPanel" --label "frontend,mvp" --body "AnalysisPanel has inline empty/error states. Dedicated components exist in analysis-results.tsx but aren't used.\n\n## Acceptance Criteria\n- [ ] Replace inline empty state with AnalysisEmptyState component\n- [ ] Replace inline error state with AnalysisErrorState component\n- [ ] Remove duplicated inline markup"
gh issue create --title "Add analysis history selector to view previous analyses" --label "frontend,mvp" --body "The getAnalyses endpoint supports paginated history but UI only shows latest.\n\n## Acceptance Criteria\n- [ ] Add dropdown/list of previous analyses with date + commit SHA\n- [ ] Clicking selects and displays that analysis\n- [ ] Current analysis highlighted"
gh issue create --title "Display language breakdown as visual bar chart" --label "frontend,enhancement" --body "Languages shown as flat badges. Add proportional visualization.\n\n## Acceptance Criteria\n- [ ] Horizontal bar chart or proportional segments for language distribution\n- [ ] Hover shows exact file count and percentage"
gh issue create --title "Show analysis branch, commit SHA, and duration in results" --label "frontend,mvp" --body "Analysis panel shows date but not branch/commit/duration.\n\n## Acceptance Criteria\n- [ ] Display branch name and truncated commit SHA in results header\n- [ ] Show analysis duration if available"
gh issue create --title "Add dark mode support to analysis results" --label "frontend,enhancement" --body "Analysis results use hardcoded light-mode Tailwind colors.\n\n## Acceptance Criteria\n- [ ] Add dark: variants to all analysis result components\n- [ ] Test in both modes"
gh issue create --title "Make analysis results responsive for mobile" --label "frontend,mvp" --body "Ensure analysis results are readable on small screens.\n\n## Acceptance Criteria\n- [ ] Summary cards stack on mobile\n- [ ] Plugin issues readable without horizontal scroll\n- [ ] Dependency grid single column on small screens"
# MVP #4: Error Handling & Edge Cases
gh issue create --title "Pass GitHub token to analysis for private repos + handle expiry" --label "backend,frontend,mvp" --body "Frontend doesn't pass stored GitHub token when triggering analysis. Private repos fail with confusing error.\n\n## Acceptance Criteria\n- [ ] Frontend passes user's GitHub access token when triggering analysis\n- [ ] If token expired, show Reconnect GitHub prompt\n- [ ] If no GitHub connected, show clear message for private repos"
gh issue create --title "Add retry with backoff for rate-limited analysis (429)" --label "backend,frontend,mvp" --body "Rate limit errors are caught but no retry mechanism exists.\n\n## Acceptance Criteria\n- [ ] Show countdown timer on 429\n- [ ] Optional auto-retry after backoff\n- [ ] Show rate limit info if available"
gh issue create --title "Add timeout for large repository analysis" --label "backend,mvp" --body "No timeout on analyzeRepository. Large repos could hang.\n\n## Acceptance Criteria\n- [ ] Configurable timeout (default 120s)\n- [ ] Clear timeout error message\n- [ ] Expose maxFiles/maxFileSizeBytes options in UI"
gh issue create --title "Add toast notification system for analysis events" --label "frontend,mvp" --body "No toast/notification system. Errors only shown inline.\n\n## Acceptance Criteria\n- [ ] Success toast on analysis complete\n- [ ] Error toast on failure\n- [ ] Auto-dismiss after 5s"
gh issue create --title "Add React Error Boundary around AnalysisResults" --label "frontend,mvp" --body "Unexpected data shapes crash the page with no recovery.\n\n## Acceptance Criteria\n- [ ] Error Boundary wrapping AnalysisResults\n- [ ] Fallback UI with raw JSON toggle\n- [ ] Error logged to console"
gh issue create --title "Validate StoredAnalysis data shape before rendering" --label "frontend,mvp" --body "AnalysisResults accesses nested properties without null checks.\n\n## Acceptance Criteria\n- [ ] Runtime validation of StoredAnalysis shape\n- [ ] Graceful handling of missing sections\n- [ ] Handle empty results array"
gh issue create --title "Show specific UI guidance for repo-not-found errors" --label "frontend,mvp" --body "404 errors show generic message without actionable guidance.\n\n## Acceptance Criteria\n- [ ] Specific error card for repo-not-found\n- [ ] Suggest: check URL, connect GitHub for private repos\n- [ ] Link to project settings to update URL"
# MVP #5: Demo/Deploy Environment
gh issue create --title "Create docker-compose.demo.yml for one-command demo" --label "devops,mvp" --body "Current docker-compose.yml has placeholder values. No one-command demo.\n\n## Acceptance Criteria\n- [ ] docker-compose.demo.yml with sensible defaults\n- [ ] Inline GitHub OAuth setup instructions\n- [ ] Auto-run DB migrations on startup\n- [ ] Health checks confirm all services up"
gh issue create --title "Add first-time demo setup script" --label "devops,mvp" --body "Too many manual steps to run demo.\n\n## Acceptance Criteria\n- [ ] scripts/demo-setup.sh that copies env, prompts for OAuth creds, generates secrets, starts docker, runs migrations, prints URLs\n- [ ] Documented in README"
gh issue create --title "Fail-fast environment variable validation on startup" --label "backend,mvp" --body "Unclear if app fails fast on missing critical env vars.\n\n## Acceptance Criteria\n- [ ] App exits with clear error on missing required vars\n- [ ] Distinguish required vs optional\n- [ ] Log which vars missing (not values)"
gh issue create --title "Document OAuth callback URLs for different environments" --label "docs,mvp" --body "Only localhost callback URL documented.\n\n## Acceptance Criteria\n- [ ] docs/deployment/oauth-setup.md covering local, Docker, production URLs\n- [ ] Common pitfalls documented\n- [ ] Linked from README"
gh issue create --title "Add /health endpoint to API service" --label "backend,devops,mvp" --body "No health check endpoint. Docker uses service_started instead of service_healthy.\n\n## Acceptance Criteria\n- [ ] GET /health checks DB connectivity\n- [ ] docker-compose.yml updated to use service_healthy\n- [ ] Returns { status: ok, db: connected }"