Skip to content

Commit c895ca1

Browse files
fotescodevclaude
andcommitted
docs: add solution documentation for variant routing and resume fallback
Documents two production issues and their solutions: - Production variant routes redirecting to base URL (Convex URL + publish status) - Resume link redirect fallback for variants without generated PDFs Includes prevention strategies and variant-resume pairing workflow. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 772662d commit c895ca1

2 files changed

Lines changed: 402 additions & 0 deletions

File tree

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
---
2+
title: "Production Variant Routes Redirect to Base URL"
3+
type: "deployment-issue"
4+
severity: "high"
5+
status: "resolved"
6+
date_identified: "2026-01-13"
7+
date_resolved: "2026-01-13"
8+
9+
category: "deployment-issue"
10+
component: "Variant Portfolio (src/pages/VariantPortfolio.tsx)"
11+
subsystem: "Environment configuration & variant publishing"
12+
13+
symptoms:
14+
- "Navigating to variant URLs (e.g., edgeoftrust.com/notion/senior-product-manager) shows 'Loading...' then redirects to '/'"
15+
- "Console shows 404 error for the route"
16+
- "React app loads successfully with 200 status on all assets"
17+
- "Variant data exists in Convex database but is not displayed"
18+
19+
root_cause: |
20+
Two-part failure in variant delivery pipeline:
21+
1. GitHub Actions secret VITE_CONVEX_URL pointed to wrong Convex instance (happy-otter-123.convex.cloud instead of scintillating-husky-549.convex.cloud)
22+
2. Variant publishStatus was "draft" instead of "published" - the getBySlug query filters unpublished variants
23+
24+
affected_files:
25+
- path: ".github/workflows/deploy.yml"
26+
description: "GitHub Actions workflow referencing VITE_CONVEX_URL secret"
27+
- path: "src/pages/VariantPortfolio.tsx"
28+
description: "Page component that loads variant data via useVariant hook"
29+
- path: "src/lib/variants.ts"
30+
description: "useVariant hook that fetches variant from Convex"
31+
- path: "convex/variants.ts"
32+
description: "getBySlug query that filters by publishStatus === 'published'"
33+
34+
tags: [deployment, environment-configuration, convex, variant-routing, github-actions, database-status]
35+
---
36+
37+
# Production Variant Routes Redirect to Base URL
38+
39+
## Problem
40+
41+
Variant portfolio routes (e.g., `edgeoftrust.com/notion/senior-product-manager`) were showing "Loading..." briefly then redirecting to the home page instead of displaying the personalized portfolio variant.
42+
43+
### Symptoms
44+
45+
1. Page shows "Loading..." text briefly
46+
2. Immediately redirects to `/` (home page)
47+
3. Console shows 404 error for the route itself
48+
4. All JavaScript assets load successfully (200 status)
49+
5. Variant data confirmed to exist in Convex database
50+
51+
## Investigation
52+
53+
### Step 1: Verify SPA Routing
54+
```bash
55+
# Check if 404.html exists (needed for GitHub Pages SPA routing)
56+
curl -s "https://edgeoftrust.com/404.html" | head -20
57+
# Result: 404.html exists and contains the SPA shell
58+
```
59+
60+
### Step 2: Check Network Requests
61+
Browser dev tools showed all assets loading correctly. The issue was not with asset delivery.
62+
63+
### Step 3: Verify Variant Exists in Database
64+
```bash
65+
npx convex run variants:listAll | grep -i "notion"
66+
# Result: Variant exists with slug "notion-senior-product-manager"
67+
```
68+
69+
### Step 4: Compare Convex URLs
70+
```bash
71+
# Check URL in production bundle
72+
curl -s "https://edgeoftrust.com/assets/index-*.js" | grep -oE "https://[a-z0-9-]+\.convex\.cloud"
73+
# Result: https://happy-otter-123.convex.cloud
74+
75+
# Check local .env.local
76+
cat .env.local | grep VITE_CONVEX_URL
77+
# Result: https://scintillating-husky-549.convex.cloud
78+
```
79+
80+
**Finding**: Production bundle had wrong Convex URL!
81+
82+
### Step 5: Check Variant Publish Status
83+
```bash
84+
npx convex run variants:listAll | grep -A5 "notion"
85+
# Result: publishStatus: "draft"
86+
```
87+
88+
**Finding**: Variant was not published!
89+
90+
## Root Causes
91+
92+
### Cause 1: Wrong Convex URL in GitHub Secret
93+
94+
The `VITE_CONVEX_URL` GitHub Actions secret was set to an old/test Convex deployment:
95+
- **Production had**: `https://happy-otter-123.convex.cloud`
96+
- **Should have been**: `https://scintillating-husky-549.convex.cloud`
97+
98+
This caused the production app to query a different Convex database that didn't have the variant data.
99+
100+
### Cause 2: Variant Not Published
101+
102+
The `getBySlug` query in `convex/variants.ts` filters by publish status:
103+
104+
```typescript
105+
// convex/variants.ts:32
106+
if (!variant || variant.publishStatus !== "published") {
107+
return null;
108+
}
109+
```
110+
111+
The variant had `publishStatus: "draft"`, so the query returned `null`, triggering the redirect in `VariantPortfolio.tsx`:
112+
113+
```typescript
114+
// src/pages/VariantPortfolio.tsx:52-54
115+
if (!variant) {
116+
return <Navigate to="/" replace />;
117+
}
118+
```
119+
120+
## Solution
121+
122+
### Fix 1: Update GitHub Secret
123+
124+
```bash
125+
# Delete and recreate the secret with correct URL
126+
gh secret delete VITE_CONVEX_URL --repo fotescodev/portfolio
127+
gh secret set VITE_CONVEX_URL --body "https://scintillating-husky-549.convex.cloud" --repo fotescodev/portfolio
128+
129+
# Trigger redeployment
130+
gh workflow run "Deploy to GitHub Pages" --repo fotescodev/portfolio
131+
```
132+
133+
### Fix 2: Publish the Variant
134+
135+
```bash
136+
npx convex run variants:updateStatus '{"slug": "notion-senior-product-manager", "publishStatus": "published"}'
137+
```
138+
139+
### Verification
140+
141+
```bash
142+
# Confirm variant is now published
143+
npx convex run variants:listAll | grep -A2 "notion"
144+
# publishStatus: "published"
145+
146+
# Test production URL
147+
curl -sI "https://edgeoftrust.com/notion/senior-product-manager"
148+
# Page loads correctly with variant content
149+
```
150+
151+
## Prevention
152+
153+
### 1. Pre-Deployment Checklist
154+
155+
- [ ] Verify `VITE_CONVEX_URL` secret matches production Convex deployment
156+
- [ ] Run `npx convex run variants:listAll` to confirm target variants are published
157+
- [ ] Test variant URL locally before deploying
158+
159+
### 2. Convex URL Validation Script
160+
161+
```typescript
162+
// scripts/verify-convex-url.ts
163+
const expectedUrl = "https://scintillating-husky-549.convex.cloud";
164+
const envUrl = process.env.VITE_CONVEX_URL;
165+
166+
if (envUrl !== expectedUrl) {
167+
console.error(`VITE_CONVEX_URL mismatch!`);
168+
console.error(`Expected: ${expectedUrl}`);
169+
console.error(`Got: ${envUrl}`);
170+
process.exit(1);
171+
}
172+
```
173+
174+
### 3. Variant Status Validation
175+
176+
```typescript
177+
// scripts/check-variant-publishing.ts
178+
// Run before deployment to ensure target variants are published
179+
const draftVariants = variants.filter(v => v.publishStatus === "draft");
180+
if (draftVariants.length > 0) {
181+
console.warn("Draft variants found:", draftVariants.map(v => v.slug));
182+
}
183+
```
184+
185+
### 4. Post-Deploy Verification
186+
187+
After each deployment, verify:
188+
1. Production bundle contains correct Convex URL
189+
2. At least one variant route loads successfully
190+
3. Resume links work (or fall back gracefully)
191+
192+
## Related Issues
193+
194+
- `docs/solutions/integration-issues/react-router-static-file-interception.md` - SPA routing issues
195+
- `docs/solutions/integration-issues/cv-dashboard-dev-port-configuration.md` - DEV mode configuration
196+
197+
## Key Learnings
198+
199+
1. **Environment variables are embedded at build time** - Vite bakes `VITE_*` vars into the bundle. Changing a secret requires a rebuild.
200+
201+
2. **Two-stage variant delivery** - Variants must be both:
202+
- Stored in the correct Convex deployment (via `VITE_CONVEX_URL`)
203+
- Published (`publishStatus: "published"`)
204+
205+
3. **Silent failures are dangerous** - The redirect to home gave no indication of the actual problem. Consider adding error states or logging for debugging.

0 commit comments

Comments
 (0)