Owner: whoever owns user-profile (unassigned) · Priority: Medium — does not block rollout of the Redis approach elsewhere.
Description
UserProfileService (src/user-profile/user-profile.service.ts) stores profiles in a Map<id, UserProfile> plus a Map<walletAddress, id> secondary index, both process-local. Follow-up from the persistence spike (#181) — see backend/PERSISTENT_STORAGE_SPIKE.md (§2) for the full write-up.
The one wrinkle: search() does a substring match across name, bio, and skills. Redis has no native equivalent at this data size without adding a separate search module (e.g. RediSearch), which isn't guaranteed available on every Redis deployment. Recommendation is to keep search() scanning findAll()'s results in-process after migration — same behavior as today, just backed by Redis instead of the Map — and only revisit proper search indexing if profile volume makes that too slow later.
Tasks
Acceptance Criteria
Estimated Time
1-2 days
Owner: whoever owns user-profile (unassigned) · Priority: Medium — does not block rollout of the Redis approach elsewhere.
Description
UserProfileService(src/user-profile/user-profile.service.ts) stores profiles in aMap<id, UserProfile>plus aMap<walletAddress, id>secondary index, both process-local. Follow-up from the persistence spike (#181) — seebackend/PERSISTENT_STORAGE_SPIKE.md(§2) for the full write-up.The one wrinkle:
search()does a substring match acrossname,bio, andskills. Redis has no native equivalent at this data size without adding a separate search module (e.g. RediSearch), which isn't guaranteed available on every Redis deployment. Recommendation is to keepsearch()scanningfindAll()'s results in-process after migration — same behavior as today, just backed by Redis instead of the Map — and only revisit proper search indexing if profile volume makes that too slow later.Tasks
SET profile:{id} <json>,walletAddress -> idindex as a Redis string (GET/SET), following the same pattern asGigService's prototype in Spike: Persistent, multi-instance-safe storage strategy to replace in-memory service state #181 — including its transaction-result verification, fallback metric, and production fail-fast behaviorsearch()as an in-process scan overfindAll()(no new search infra)errorlevel, matchingGigService/NonceStoreServiceUserProfileControllerand any other callers for the resulting async signature changes (most methods are alreadyasynctoday, so this should be low-friction)Acceptance Criteria
create())user-profile.service.spec.ts/user-profile.controller.spec.tstests still pass, updated for the new storeEstimated Time
1-2 days