Description
Currently the API stores the IPFS CID on the gist record but never fetches full content back from IPFS. This issue adds GET /gists/:id/content that retrieves and returns the full JSON content from IPFS using the stored CID.
Context
- The Gist entity has a content_cid field
- The IpfsService has pinJson() but no getJson() method yet
- IPFS content is fetched via an IPFS gateway, configurable via env, defaulting to https://gateway.pinata.cloud/ipfs
- The full gist content stored on IPFS is a JSON object: { text, lat, lon, timestamp }
Requirements
- Add getJson(cid: string) method to IpfsService
- Fetch from IPFS gateway: GET IPFS_GATEWAY/cid
- Add retry logic — max 3 attempts, 500ms backoff — for gateway failures
- Add GET /gists/:id/content route to GistsController
- The route fetches the gist by ID, gets the content_cid, then fetches from IPFS
- Return 404 if gist not found, 502 if IPFS gateway unreachable
- Cache the IPFS response in-memory for 5 minutes using a Map to avoid repeated gateway calls
Files to Touch
- Backend/src/ipfs/ipfs.service.ts — add getJson method with retry logic
- Backend/src/gists/gists.controller.ts — add @get(':id/content') route
- Backend/src/gists/gists.service.ts — add getGistContent method
- Backend/src/config/configuration.ts — add IPFS_GATEWAY config key
- Backend/.env.example — add IPFS_GATEWAY=https://gateway.pinata.cloud/ipfs
getJson Implementation Reference
async getJson(cid: string): Promise<Record<string, unknown>> {
const url = `${this.gateway}/${cid}`;
const response = await fetch(url);
if (!response.ok) throw new Error(`IPFS gateway error: ${response.status}`);
return response.json();
}
Acceptance Criteria
Complexity: 250 points
Description
Currently the API stores the IPFS CID on the gist record but never fetches full content back from IPFS. This issue adds GET /gists/:id/content that retrieves and returns the full JSON content from IPFS using the stored CID.
Context
Requirements
Files to Touch
getJson Implementation Reference
Acceptance Criteria
Complexity: 250 points