Merchant Portal β Rolling Plan β
Created: 2026-03-29 Status: Active β merchant-venue association shipped; offers and consumer-app tether next Last Updated: 2026-04-22
"Can we create a smooth beaver?" β working title for the merchant monetization path. A beaver builds; smooth means the experience is friction-free for venue owners.
Overview β
This document tracks the rolling implementation of the Lantern merchant portal across iterations. Each section records what shipped and what's next. The goal: let venue owners manage their presence, run promotions, and eventually see consumer-app analytics β all through the admin portal.
Shipped β
Ad Placeholder Components β β
Commit de79322 (PR #321 / #322 merge to dev).
ChatOfferPillandFeedOfferCardrenderers for the two missing placement types.AdSlotrouting component.offerNormalizerutility.- Live preview section in
OfferFormrenders all 4 placements in real-time as merchants fill in fields.
Merchant Portal in Admin App β Phases 1 & 2 β β
Commits f800589, 5202f37 (Phase 1 + auth wiring).
checkMerchantRole()inapps/web/src/lib/auth.jsandapps/admin/src/firebase.js, mirroringcheckAdminRole().isMerchantstate alongsideisAdminin both App.jsx files.- PILOT_MODE gate (consumer) and admin access gate accept admin OR merchant.
- Merchants sub-nav (admin app): expandable with Overview, Offers, Create Merchant sub-items.
- Merchants see only Merchants section; admins get full nav including admin-only sub-items.
Merchant Create / Edit / Detail / Directory β β
Commits 19dadee, 89b9d5a, 35b57b1, 58a3db5.
- Hardened merchant creation end-to-end (validation, error states).
- MerchantDetail page with redirect after create.
- All Merchants directory view (admin only).
- Edit mode on MerchantDetail + PATCH update endpoint.
Merchant β Venue Association β β
Commits d02ee1b through 4abe4d1 (19 commits).
- New
merchants/{merchantId}entity withm_*id; schema introduces stable identifier separate from user uid (#231 prep). - Six new
/auth/admin/merchants/*endpoints (list, detail, associate, disassociate) + modified POST/PATCH merchant endpoints. AdminVenuePickercomponent + functional Venues section onMerchantDetail.MerchantsAllreshaped to query merchants collection directly.- Firestore rules:
isMerchantOf()helper + merchants match + venues update rule. - Composite index for (status, createdAt) on merchants.
- OpenAPI spec updated for all new/changed routes.
- Design + plan docs committed before implementation.
Out of scope (deliberately) β
These were explicitly deferred during design reviews and will not land in the merchant portal iterations tracked here. Each should get its own project plan when the time comes.
- Multi-user per merchant (#231) β one user β one merchant today; junction table approach needed.
- Self-service merchant signup (#136) β admin-created only for now; claim workflow depends on #136.
- Zero-knowledge encryption for merchant accounts β merchant auth intentionally uses standard Firebase email/password with no ZKE passphrase, because merchants need multi-device access and standard password recovery.
- Food-court / sub-venue model β deliberate non-feature; complex venue hierarchy not planned.
- Venue deletion flow β no delete endpoint today; stale references are a low-probability edge case.
Next candidates β
Ordered by dependency and value. Items marked (unblocked) became unblocked when merchant-venue association shipped.
Multi-user per merchant (#231) β junior items:
merchantUsersjunction collection, admin UI to add/remove users from a merchant, updateisMerchantOf()to use junction. Depends on stablemerchantId(now shipped).Venue onboarding β let merchants (or admins on their behalf) add a net-new venue that isn't in the existing OSM-sourced directory. Produces a
venuesdoc withsource: 'merchant', pending admin approval. Was "Path 2" from Q3 in the association design spec. Depends on venue association (now shipped).Merchant analytics read β
/auth/admin/merchants/:merchantId/analyticspulling from BigQuery or the analytics-api. Depends on stable merchantId + venueId references (now shipped).Firestore rules: merchant self-read β let authenticated merchant users read their own
merchants/{merchantId}doc (today only admins can). Unblocks a future merchant-facing portal outside the admin app.Offers UI β create/edit/delete β functional offer management in the admin app.
AdSlotcomponents andOfferFormexist; the gap is CRUD endpoints on offers collection and wiring the form to save. (unblocked β depends on stable merchantId, now shipped)Consumer-app tether β surface active offers in the consumer web app's venue view and dashboard. Depends on Offers UI (#5 above) and stable venueβmerchant references. (unblocked β venue association now shipped)
Deferred (longer-horizon) β
- Self-service merchant onboarding β public signup flow, invite link, email verification, admin approval step. Needs #136 complete first.
- Merchant-facing dashboard (standalone) β break merchant experience out of the admin app into its own surface, or a deep-linked view. Currently merchants sign into the admin app; long-term that's awkward.
- Offer scheduling and targeting β time-based activation, audience filters (proximity, gender, age). Post-MVP.
- Revenue / billing β connecting offers to impressions/redemptions for billing purposes. Needs analytics pipeline first.