Skip to content

docs: add PRD for product tags feature - #665

Merged
mnindrazaka merged 2 commits into
feat/tagsfrom
claude/cool-gates-yglasm
Oct 1, 2026
Merged

mnindrazaka merged 2 commits into
feat/tagsfrom
claude/cool-gates-yglasm

Conversation

@mnindrazaka

Copy link
Copy Markdown
Collaborator

Add a comprehensive Product Requirements Document for the product tags feature, enabling merchants to mark items as "New", "Best Seller", or other custom tags with highlighted sections in the order app menu.

Summary

This PRD defines a complete feature for tagging products and variants with merchandising labels. Tags attach to variants at the storage layer, with product-level scope derived when all live variants carry the same tag. The design handles three key cases: tagging a single variant of a multi-variant product (e.g., "New: Pancong Ice Cream"), tagging a single-variant product (e.g., "New: Salted Caramel Macchiato"), and tagging all variants of a product (e.g., "Best Seller: Coffee Latte").

Key sections

  • Problem statement — current system has no tag concept; product cards and menu have nowhere to display recommendations
  • Design rationale — compares four options and selects variant-level storage with derived product scope (Option D) to avoid two sources of truth while handling all three use cases
  • Data model — three tables: tags (name, colour, highlight flag, sort order), variant_tags (join table), and variants.image_url (new column)
  • Feature requirements — six features spanning tag CRUD, assignment UI, variant form integration, API responses, badge rendering, and highlight sections in the order app menu
  • Design decisions — 15 numbered decisions covering storage strategy, resolution rules, colour palette, pre-fill logic, and scope rules
  • Phased plan — 13 phases with dependency graph, each leaving the product shippable and testable independently; phases 1–2 can run in parallel, then waves of 2–3 phases each
  • Risks and mitigations — addresses silent demotion on variant add (mitigated by pre-fill), stale tags (manual removal), clutter (max 2 badges, carousels), and load (preloaded on existing query)

Implementation notes

The design is grounded in observed patterns from delivery marketplaces (GoFood, GrabFood, ShopeeFood) and avoids two common pitfalls: storing tags at both product and variant level (creates inheritance ambiguity), and tagging option values (breaks multi-option variants). The resolution rule is a pure function (ResolveProductTags) computed server-side on every product read, ensuring both POS and order app see the same answer without re-implementing logic.

The phased plan is structured to allow parallel work: API CRUD and variant image can start immediately; assignment and resolution APIs can follow; frontend work (use cases, screens, components) can proceed in parallel with API phases; customer-visible features (badges, highlight sections) land last, allowing pre-loading of tags before any reveal.

https://claude.ai/code/session_01DFf8Zw5nWptg6TQFcXnQ6X

@vercel

vercel Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

3 Skipped Deployments
Project Deployment Actions Updated
gatherloop-order Ignored Ignored Oct 1, 2026 9:56am UTC
gatherloop-pos Ignored Ignored Oct 1, 2026 9:56am UTC
gatherloop-ui-storybook Ignored Ignored Oct 1, 2026 9:56am UTC

@mnindrazaka
mnindrazaka changed the base branch from main to feat/tags October 1, 2026 09:50
Highlighted tags become filter chips, highlight entries sort newest-tagged
first, and sections stay uncapped carousels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFf8Zw5nWptg6TQFcXnQ6X
@mnindrazaka
mnindrazaka merged commit f7c2067 into feat/tags Oct 1, 2026
4 checks passed
mnindrazaka added a commit that referenced this pull request Oct 2, 2026
* docs: add PRD for product tags feature (#665)

* docs: add PRD for product tags and order app highlight sections

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFf8Zw5nWptg6TQFcXnQ6X

* docs: settle product tags open questions

Highlighted tags become filter chips, highlight entries sort newest-tagged
first, and sections stay uncapped carousels.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DFf8Zw5nWptg6TQFcXnQ6X

---------

Co-authored-by: Claude <noreply@anthropic.com>

* feat(api): add tag CRUD endpoints (#666)

Phase 1 of docs/prd-product-tags.md: tags table migration, Tag domain
entity with colour palette validation, case-insensitive unique name
check, MySQL repository, REST handler/routes under CheckAuth, and the
/tags contract.


Claude-Session: https://claude.ai/code/session_01TvErk6zGfrEZmJLbQVmtLA

Co-authored-by: Claude <noreply@anthropic.com>

* feat(variants): add optional image URL to variants (#667)

Phase 2 of product tags (docs/prd-product-tags.md). Adds variants.image_url
(migration 000045), threads imageUrl through the Go domain, MySQL and REST
layers, the OpenAPI contract, and the POS variant form. No reader uses it yet.


Claude-Session: https://claude.ai/code/session_01EqQBJZutniFv8dssVNZE1t

Co-authored-by: Claude <noreply@anthropic.com>

* feat(api): add variant-tag assignment endpoints (#669)

Add the variant_tags join table, PUT /tags/{tagId}/variants and optional
VariantRequest.tagIds. Both write paths diff against the stored pairs so
untouched rows keep their created_at, which later orders highlight
entries by taggedAt. Omitted tagIds leave a variant's tags alone.

Variant reads preload their tags, and tag reads return variantCount for
the delete confirmation.

Also renumber add_variant_image_url to 000046: it collided with
000045_create_tags, which golang-migrate rejects as a duplicate version.


Claude-Session: https://claude.ai/code/session_01FXmvmGqaJhBHmyYxbbeHoX

Co-authored-by: Claude <noreply@anthropic.com>

* feat(ui): add tag entity, repository and CRUD use cases (#668)

Claude-Session: https://claude.ai/code/session_01Bue7Cr3LqJkJwVwJNi82E6

Co-authored-by: Claude <noreply@anthropic.com>

* feat(api): resolve product tags on product reads (#670)

Add ProductTag and ResolveProductTags, derive product vs variant scope
over live variants, and expose Product.tags on authenticated and public
product endpoints.


Claude-Session: https://claude.ai/code/session_01FQbRptVGsQxpRkvxiR3fwN

Co-authored-by: Claude <noreply@anthropic.com>

* feat(pos): add tag management screens (#671)

Add TagList/TagCreate/TagUpdate screens, handlers and composition roots,
TagFormView with colour swatch picker, TagListItem, TagDeleteAlert, POS
pages under /tags and a Tags sidebar entry. Tag gains variantCount for the
list item and the delete confirmation.


Claude-Session: https://claude.ai/code/session_01LcTrodMYofppndzqZwi9mC

Co-authored-by: Claude <noreply@anthropic.com>

* feat(variants): add tag multi-select to POS variant form (#672)

Phase 8 of product tags (docs/prd-product-tags.md). The variant form gains a
tag multi-select; create and update handlers load tags via TagListUsecase.
tagIds is sent on every submit, and create pre-fills the parent product's
product-scope tags (D4) once Product.tags is populated.


Claude-Session: https://claude.ai/code/session_01NBJmPLfgeRgnjk2NNGueuK

Co-authored-by: Claude <noreply@anthropic.com>

* feat(pos): add tag assignment screen (#673)

Add TagAssignmentUsecase (load all variants, TOGGLE_VARIANT, tri-state
TOGGLE_PRODUCT, SEARCH, SAVE via TagRepository.setTagVariants),
TagAssignmentScreen grouped by category > product > variants with
single-variant products collapsed to one checkbox, handler, composition
root, page at /tags/[tagId]/assign and an "Assign products" action on
the tag list item.


Claude-Session: https://claude.ai/code/session_01438CoGpchErzXVWnCgQi6A

Co-authored-by: Claude <noreply@anthropic.com>

* feat(ui): add product/variant tags, TagBadge and buildTagHighlights (#674)

Claude-Session: https://claude.ai/code/session_019gSoWCarkoZ2wv1oRZCgex

Co-authored-by: Claude <noreply@anthropic.com>

* feat(ui): show tag badges on POS product cards (#675)

Claude-Session: https://claude.ai/code/session_01CDrcbE4NkTbQssA1ohgz1D

Co-authored-by: Claude <noreply@anthropic.com>

* feat(order): show tag badges on menu cards and item detail (#676)

Claude-Session: https://claude.ai/code/session_011NpuEcKaprJtcmS59gihhz

Co-authored-by: Claude <noreply@anthropic.com>

* feat(order): add highlight sections to the menu list (#677)

Render one horizontal carousel per highlighted tag above the category
groups, only while the search box is empty and no category is selected.
SELECT_ITEM now carries an optional variantId so tapping a variant card
opens the item sheet with that variant's option values preselected.


Claude-Session: https://claude.ai/code/session_01GWVBoUtiTrYsEwcM4T6hgo

Co-authored-by: Claude <noreply@anthropic.com>

* feat(order): add highlighted-tag chips to the menu list (#678)

Render one chip per highlighted tag with entries between Semua and the
categories, in the tag's colour. Selecting a tag shows that tag's entries
as a vertical list of full-width cards, newest-tagged first, replacing the
category groups. MenuListUsecase gains selectedTagId, mutually exclusive
with selectedCategoryId.


Claude-Session: https://claude.ai/code/session_01TLnh5DyR2sQw11gzZEMbFW

Co-authored-by: Claude <noreply@anthropic.com>

* docs(tags): add Tags docs page and pos/order e2e coverage (#679)

- docs-site: Tags page with screenshot, wired into the Catalog sidebar
- pos-web-e2e: create a tag, assign it to a product, see the badge in the
  transaction item picker, delete it
- order-web-e2e: highlight section above categories, variant card
  pre-selects its option, tag chip filters the menu, sections hide on search
- fix(ui): add missing tags to createMenuVariants mock so order-web builds


Claude-Session: https://claude.ai/code/session_01GCdTMSXXkEz4QkhzwCkQJ6

Co-authored-by: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants