Practitionist / Practitionist/elluminar_web
Search & recommendations upgrade + soft-bundle upsells
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1
- Forks
- 0
- Avg merge
- 17h 2m
- Merged PRs (30d)
- 18
Description
Why / Context
MVP discovery is Postgres FTS (GIN indexes on Course/Project) — fine for launch scale, weak on typo tolerance, faceting speed, and ranking. Marketplace network effects (teardown §5.3: learners who came for one creator discovering others) need real search + cross-creator recommendations + the PRD §6.5 "soft bundle" upsells at checkout (never forced).
Schema already in place — NO migration required
- Course/Project catalog fields (tags, category, level, tier, ratingAvg, enrollmentCount) are the index document source
Bundle/BundleItem+ Price(BUNDLE) for soft-bundle upsells (tables dormant since MVP)- OrderItem history powers "learners also bought" co-purchase signals
Implementation plan
- Pick engine: Typesense Cloud vs Meilisearch (decision doc: typo tolerance, facets, geo-free, cost) — default Typesense.
- Index pipeline (
src/lib/search/indexer.ts): denormalized docs for courses/projects/creators; sync on publish/update/archive (after-write hooks in the publish actions) + nightly full rebuild function. - Search API + UI: instant search with facets (category, level, tier, price band, rating, language, creator), typo tolerance, synonyms (js/javascript); replace FTS route while keeping FTS as fallback flag.
- Ranking: tune with weights (title > tags > description) + popularity boosts (enrollmentCount, ratingAvg with Bayesian floor).
- Recommendations v1 (SQL, no ML): "learners also bought" from OrderItem co-occurrence; "more from this creator"; "next after this course" from category+level ladders — precomputed nightly into a cache table? No — keep in a materialized view via ADDITIVE migration if needed (allowed) or Redis-free JSON cache on the doc.
- Soft-bundle upsells: creator defines
Bundles in studio; checkout shows "add the mentor-guided capstone for this course at X% off" (PRD's exact pattern) — cart applies bundle discount when both members present. - Search analytics: log queries/zero-result terms (PostHog, issue #12) to feed synonyms and content gaps.
- Storefront-scoped search (tenant filter) reusing the same index.
Acceptance criteria
- Typo'd query ("javascrpt") returns relevant results with facets under 100ms p95 (engine-side)
- Publishing/unpublishing reflects in search within a minute
- Course detail shows "also bought" and creator cross-sell modules
- Checkout surfaces a soft-bundle suggestion when applicable; discount applies correctly and remains optional
- Zero-result queries logged and reviewable
Dependencies / sequencing
- MVP M6 (catalog) required; issue #12 for analytics loop
- Bundles UI unlocks the dormant Bundle tables
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the implementation plan, the existing catalog data, and src/lib/search/indexer.ts, then trace the publish actions and dependencies on MVP M6 and issue #12. Done means the listed search, recommendation, optional bundle-discount, and zero-result analytics acceptance criteria are met without a migration unless the plan requires one.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, typescript
- Domain
- analytics, backend-api-design, databases, frontend, payments, search
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100