# Product Requirements Document

## Validation Checklist

- [x] All required sections are complete
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Problem statement is specific and measurable
- [x] Problem is validated by evidence (not assumptions)
- [x] Context → Problem → Solution flow makes sense
- [x] Every persona has at least one user journey
- [x] All MoSCoW categories addressed (Must/Should/Could/Won't)
- [x] Every feature has testable acceptance criteria
- [x] Every metric has corresponding tracking events
- [x] No feature redundancy (check for duplicates)
- [x] No contradictions between sections
- [x] No technical implementation details included
- [x] A new team member could understand this PRD

---

## Product Overview

### Vision

Give store managers complete control over how their backstock is categorized, so every bin has a meaningful classification that feeds accurate floor plan and sales reporting.

### Problem Statement

Today, the backstock module forces stores to use every DRS subcategory from their POS system in the main category dropdown, even when many categories are irrelevant to their store's layout. A typical Once Upon a Child (OU) store may use only 15-20 of the 40+ DRS subcategories, meaning the dropdown is cluttered with noise. Stores work around this by creating custom categories (e.g., "Girls Clothing") which are organizationally helpful but completely invisible to floor plan reporting -- there's no way to map a custom category back to DRS sales/buys data. This creates a gap: stores that organize broadly (by department rather than individual DRS category) either lose reporting accuracy or fight a cluttered dropdown. Neither option is acceptable.

**Consequences of not solving:**
1. **Cluttered dropdowns** slow bin creation and lead to misassignment errors
2. **Custom categories break reporting** -- floor plan reports show blank/zero where custom categories are used because there's no DRS mapping
3. **No middle ground** between granular DRS categories and broad custom categories -- stores that organize by department (e.g., "Girls Tops" spanning multiple DRS codes) have no category type that fits their workflow AND feeds reports
4. **Report table readability** suffers from long POS category names with no short-name alternative

### Value Proposition

This solution gives stores three levels of category control:
1. **Curate** the DRS dropdown by hiding irrelevant categories (less noise)
2. **Create** custom categories with short names for organizational flexibility (better UX)
3. **Group** DRS categories into named bundles for broad-but-reportable classification (the missing middle ground)

The key insight is Category Groups: they let stores organize broadly while preserving a link to underlying DRS data. A "Girls Tops" group containing 5 DRS subcategories gives floor plan reports something to aggregate against, which is infinitely better than a custom category with zero DRS mapping.

## User Personas

### Primary Persona: Store Manager
- **Demographics:** 25-45, manages a single resale store, moderate tech comfort, uses backstock daily
- **Goals:** Organize backstock bins by how their store is physically laid out; get accurate floor plan reports showing what's in each zone; minimize time spent categorizing bins
- **Pain Points:** Dropdown has too many irrelevant DRS categories; has to scroll past categories their store never uses; custom categories look great organizationally but break floor plan reporting; long category names don't fit in report columns

### Secondary Persona: Regional/Multi-Store Operator
- **Demographics:** 30-55, oversees 2-10 stores, reviews reports across locations
- **Goals:** Compare backstock organization across stores; ensure floor plan reports are actionable at every location; understand inventory distribution by department
- **Pain Points:** Inconsistent categorization across stores makes comparison hard; some stores use custom categories (no reporting) while others use DRS (cluttered); no standard "department-level" grouping across stores

## User Journey Maps

### Primary Journey: Curating the Category Dropdown

1. **Awareness:** Manager notices the category dropdown has 40+ options, many of which their store never uses (e.g., they don't carry maternity items but see maternity DRS categories)
2. **Action:** Opens category management (gear icon in backstock workspace), navigates to DRS Visibility tab
3. **Configuration:** Sees all DRS subcategories with toggle switches. Turns off irrelevant categories. List updates immediately.
4. **Result:** Next time they create or edit a bin, the dropdown only shows relevant categories. Existing bins with now-hidden categories remain unchanged.
5. **Retention:** Dropdown is cleaner, bin creation is faster. New DRS categories added by POS automatically appear as visible (opt-out model).

### Secondary Journey: Creating a Category Group

1. **Awareness:** Manager organizes their store by broad departments ("Girls Tops") rather than individual DRS categories ("Girls Short Sleeve Tops 4T", "Girls Long Sleeve Tops 4T", etc.)
2. **Action:** Opens category management, navigates to Category Groups tab, clicks "Create Group"
3. **Configuration:** Names the group "Girls Tops", optionally adds a short name "Girls Tops" for reports, selects all relevant DRS subcategories from a multi-select (which shows both visible and hidden DRS categories)
4. **Result:** "Girls Tops" now appears in the main category dropdown alongside ungrouped DRS categories and custom categories. DRS categories that belong to a group no longer appear individually in the dropdown.
5. **Bin Assignment:** Assigns "Girls Tops" group to a bin. Floor plan report for that bin now aggregates sales/buys from all 5 DRS subcategories in the group.
6. **Retention:** Store's physical organization now matches the digital categorization, AND reporting works. Best of both worlds.

### Tertiary Journey: Managing Custom Categories with Short Names

1. **Awareness:** Manager has created custom categories for organizational purposes but the names are too long for report tables ("Girls Preemie/Newborn Spring Summer" won't fit in a column)
2. **Action:** Opens category management, navigates to Custom Categories tab, clicks edit on a category
3. **Configuration:** Adds a short name "Girls NB SS" that will be used in report tables instead of the full name
4. **Result:** Report tables show the short name, tooltips/detail views show the full name
5. **Note:** Custom categories still have NO DRS mapping -- they're organizational only. Reports show the short name but no sales/buys aggregation.

## Feature Requirements

### Must Have Features

#### Feature 1: Show/Hide DRS Categories
- **User Story:** As a store manager, I want to hide DRS categories my store doesn't use, so that the category dropdown only shows relevant options.
- **Acceptance Criteria:**
  - [ ] Each DRS subcategory has a visible/hidden toggle in category management
  - [ ] Hidden categories do not appear in the main category dropdown when creating/editing bins
  - [ ] Hidden categories DO still appear in Category Group member selection (hiding is about standalone dropdown only)
  - [ ] Bins already assigned to a now-hidden category retain their assignment and display correctly
  - [ ] New DRS categories added to the POS system default to visible (opt-out model)
  - [ ] Visibility settings are per-store (each store manages independently)
  - [ ] Toggling visibility is immediate (no page reload required)
  - [ ] At least one search/filter mechanism exists for stores with many DRS categories

#### Feature 2: Custom Category Short Names
- **User Story:** As a store manager, I want to add a short name to my custom categories, so that report tables are readable without truncating long names.
- **Acceptance Criteria:**
  - [ ] Custom categories have an optional `shortName` field (max ~20 characters)
  - [ ] When a short name exists, report tables display it instead of the full name
  - [ ] Full name is still visible in tooltips, detail views, and the category management UI
  - [ ] Existing custom categories without a short name continue to display their full name in reports (no breaking change)
  - [ ] Short name is editable after creation

#### Feature 3: Category Groups
- **User Story:** As a store manager, I want to group multiple DRS categories into a named group (e.g., "Girls Tops"), so that I can classify bins at a department level while preserving reportable DRS data.
- **Acceptance Criteria:**
  - [ ] Users can create named groups with an optional short name and color
  - [ ] Groups contain one or more DRS subcategories as members
  - [ ] A DRS subcategory can belong to multiple groups
  - [ ] Groups appear in the main category dropdown alongside ungrouped DRS categories and custom categories
  - [ ] DRS categories that belong to at least one group no longer appear individually in the dropdown (they're accessed via their group)
  - [ ] Selecting a group as a bin's mainCategory stores the group reference (not individual DRS codes)
  - [ ] Groups can be edited (add/remove DRS members, rename, change color) after creation
  - [ ] Groups can be deleted; bins using that group would need reassignment (prompt user)
  - [ ] Group member selection shows ALL DRS categories (including hidden ones)

#### Feature 4: Floor Plan Reporting Integration for Groups
- **User Story:** As a store manager, I want floor plan reports to show aggregated sales/buys data when a bin uses a category group, so that I get meaningful numbers even with broad categorization.
- **Acceptance Criteria:**
  - [ ] When a bin's mainCategory is a group, floor plan reports sum sales/buys from ALL DRS categories in that group
  - [ ] The group name (or short name) is displayed on floor plan reports, not the individual DRS category names
  - [ ] Custom categories still show no DRS data in reports (this is unchanged)
  - [ ] Individual DRS category assignments still show their single category's data (this is unchanged)
  - [ ] Report drill-down or tooltip reveals which DRS categories are included in the group sum

#### Feature 5: Short Name Overrides for DRS Categories and Groups
- **User Story:** As a store manager, I want to set custom short names for DRS categories and groups, so that all category types have readable report table names.
- **Acceptance Criteria:**
  - [ ] DRS subcategories have an optional store-level short name override
  - [ ] Groups have an optional short name (set during creation/edit)
  - [ ] When set, the short name is used in report tables; POS name is used as fallback
  - [ ] Short name overrides are per-store (each store can customize independently)

#### Feature 6: Category Group Visual Indicators
- **User Story:** As a store manager, I want to easily distinguish between individual categories and groups in the dropdown and on bin cards, so I know whether a category represents a single DRS code or a group of codes.
- **Acceptance Criteria:**
  - [ ] Groups have a distinct visual indicator in the dropdown (e.g., folder icon, badge showing member count like "(5 categories)")
  - [ ] Bin cards/Kanban show whether the mainCategory is a group, individual DRS, or custom category
  - [ ] Group color is applied consistently across bin cards, reports, and floor plans
  - [ ] Custom categories have a distinguishing indicator (e.g., different icon or subtle label) so all 3 types are visually distinct
  - [ ] Tooltips on group indicators reveal the member DRS category names

### Should Have Features

### Could Have Features

#### Feature 7: Bulk Reassignment Tool for Groups
- **User Story:** As a store manager, I want to migrate existing bins from individual DRS categories to a newly created group that contains those categories.
- **Acceptance Criteria:**
  - [ ] After creating a group, an optional prompt offers to migrate bins using member categories to the group
  - [ ] Migration preview shows affected bin count per category
  - [ ] Migration is optional and reversible (bins can be re-assigned individually)

#### Feature 8: Group Templates / Presets
- **User Story:** As a regional operator, I want to create category group presets that can be shared across stores of the same concept.
- **Acceptance Criteria:**
  - [ ] Preset groups can be defined at the concept level
  - [ ] Stores can import/apply a preset, creating their own copy of the group
  - [ ] Presets are suggestions only -- stores can modify their local copy

### Won't Have (This Phase)

- **Cross-store group synchronization** -- Groups are per-store, not globally enforced
- **Automatic DRS-to-group mapping suggestions** via AI or rules
- **Custom category DRS mapping** -- Custom categories remain outside the DRS reporting system; groups are the solution for reportable broad categories
- **Nested groups** (groups of groups) -- Keep the hierarchy flat: DRS categories -> groups
- **Reporting breakdown within groups** -- v1 shows the sum; individual category breakdown within a group is a future enhancement
- **Tag-level group support** -- Groups only apply to mainCategory, not to tags in bsBin_Cat

## Detailed Feature Specifications

### Feature: Category Groups (Most Complex)

**Description:** Category Groups allow a store manager to bundle multiple DRS subcategories under a single named entity. The group appears in the mainCategory dropdown, and when assigned to a bin, links that bin to all the DRS subcategories within the group for reporting purposes. This bridges the gap between granular DRS classification and broad departmental organization.

**User Flow:**
1. User opens category management modal in the backstock workspace
2. User navigates to "Category Groups" tab
3. User clicks "Create Group"
4. System shows a form with: Group Name, Short Name (optional), Color picker, DRS Category multi-select
5. User enters "Girls Tops", short name "Girls Tops", picks a pink color
6. User selects DRS categories: "Girls SS Tops 4T", "Girls LS Tops 4T", "Girls SS Tops 5", "Girls LS Tops 5", "Girls Tops 6+"
7. User clicks Save
8. System creates the group and updates the dropdown source
9. Next bin create/edit: dropdown shows "Girls Tops" (with group icon) in place of the 5 individual DRS categories
10. User assigns "Girls Tops" to a bin
11. Floor plan report for that bin shows aggregated sales/buys from all 5 DRS categories

**Business Rules:**
- Rule 1: A group must have at least 1 DRS category member
- Rule 2: A group name must be unique within the store
- Rule 3: DRS categories in groups are removed from standalone dropdown selection; they're only accessible through their group(s). If a DRS category is in multiple groups, it only appears in those groups, not standalone.
- Rule 4: If ALL groups containing a DRS category are deleted, that DRS category returns to the standalone dropdown
- Rule 5: Hidden DRS categories can still be group members (hiding only affects standalone dropdown)
- Rule 6: Deleting a group prompts the user about bins that use it. Options: reassign to a specific category/group, or set to uncategorized.
- Rule 7: Editing a group's members (add/remove DRS categories) updates reporting for ALL bins using that group going forward. Historical report snapshots are unaffected.
- Rule 8: Group reporting sums ALL member DRS categories' sales/buys data. This is an approximation, not exact per-bin attribution.
- Rule 9: When a DRS category is removed from POS, if it's a group member, the group continues to function with remaining members (graceful degradation).

**Edge Cases:**
- **Empty group after DRS removals:** If all DRS categories in a group are removed from POS, the group becomes empty. Display a warning in category management. Bins using it show "Group (0 categories)" with no reportable data.
- **DRS category in multiple groups with overlapping reporting:** If bin A uses "Girls Tops" (contains WFOU) and bin B uses "Girls Clothing" (also contains WFOU), the WFOU sales appear in both bins' reports. This is expected -- groups are approximations, not partitions.
- **Bin already has individual DRS, now that DRS is added to a group:** The bin keeps its individual DRS assignment. It is NOT auto-migrated. This is intentional -- existing categorization shouldn't change without user action.
- **User tries to create a group with only custom categories:** Blocked. Groups must contain at least 1 DRS category (custom categories have their own path).
- **Store has no DRS categories in POS:** Groups tab shows a message explaining groups require DRS categories. Custom categories are still available.

## Success Metrics

### Key Performance Indicators

- **Adoption:** 50%+ of active stores use at least one category customization feature (hide, group, or short name) within 60 days of launch
- **Engagement:** Stores that create groups assign 30%+ of their bins to groups within 90 days
- **Quality:** Floor plan reports for group-assigned bins show non-zero aggregated data in 95%+ of cases (vs 0% for custom category bins today)
- **Business Impact:** Reduction in custom category usage for bins that need reporting (custom categories shift to tags-only use, groups replace them for mainCategory)

### Tracking Requirements

| Event | Properties | Purpose |
|-------|------------|---------|
| `category_visibility_toggled` | `typeNum`, `categoryCode`, `visible` (bool) | Track adoption of show/hide feature |
| `category_group_created` | `typeNum`, `groupId`, `memberCount`, `hasShortName` | Track group creation patterns |
| `category_group_assigned_to_bin` | `typeNum`, `binId`, `groupId` | Track group adoption for bin categorization |
| `custom_category_shortname_set` | `typeNum`, `categoryId`, `hasShortName` | Track short name adoption |
| `drs_shortname_override_set` | `typeNum`, `categoryCode`, `shortName` | Track DRS short name customization |
| `category_group_deleted` | `typeNum`, `groupId`, `affectedBinCount` | Track group lifecycle |
| `category_group_edited` | `typeNum`, `groupId`, `action` (add_member/remove_member/rename) | Track group maintenance |

---

## Constraints and Assumptions

### Constraints
- Must work within the existing `bsBins.mainCategory` VARCHAR(20) column (group storage format must fit)
- Must not break existing floor plan reporting for bins with individual DRS categories
- Must not break existing custom category functionality
- Category management UI must fit within the existing modal pattern (expandable with tabs)
- Migration system must be used for all schema changes (no manual SQL)
- Per-store settings mean each store DB carries its own configuration

### Assumptions
- Stores have DRS subcategories loaded in `kiosk_sales.subcategories` for their concept
- Floor plan reporting queries can be modified to support group-to-DRS expansion
- The Syncfusion DropDownList/MultiSelect components support grouped/sectioned display
- Store managers are comfortable with a tabbed category management interface
- Most stores will use 1-10 groups, not hundreds

## Risks and Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Group reporting shows inflated numbers (sum of all member categories) | Medium | High | Clearly label group-sourced numbers as "estimated" or "group aggregate". Tooltip shows member list. |
| DRS categories in multiple groups cause confusion about where to find them | Medium | Medium | Clear visual indicators showing group membership. Search/filter in dropdown. |
| Migration complexity for `mainCategory` column to support group references | High | Medium | Use a prefix convention (e.g., `grp_123`) to distinguish group IDs from DRS codes in VARCHAR(20) |
| Performance impact of expanding groups to DRS codes for reporting queries | Medium | Low | Groups typically contain 3-10 members. JOIN expansion is lightweight. Cache group-to-DRS mapping. |
| Stores create too many groups, making dropdown equally cluttered | Low | Low | No limit needed initially. Monitor via analytics. |

## Open Questions

- [x] Per-store vs per-concept visibility → **Per-store**
- [x] Group replaces mainCategory vs auto-populates tags → **Replaces mainCategory**
- [x] Reporting aggregation method → **Sum all categories in group**
- [x] Hide behavior for existing bins → **Hide from dropdown only**
- [x] DRS category exclusivity in groups → **Multiple groups allowed**
- [x] Short name scope → **All category types**
- [x] Floor plan display for groups → **Group name**
- [x] Hidden DRS in groups → **Still in groups**
- [x] Dropdown behavior for grouped DRS → **Groups OR ungrouped individuals**
- [x] Existing bin migration when DRS added to group → **Keep individual assignment**

---

## Supporting Research

### Competitive Analysis
Resale/consignment store management systems typically offer flat category lists with no grouping. The category group concept is a differentiator that bridges POS reporting with flexible store organization -- no direct competitor offers this.

### User Research
Based on observed store behavior: stores that use custom categories for broad organization (e.g., "Girls Clothing") consistently have gaps in their floor plan reports. They've chosen organizational convenience over reporting accuracy. Category Groups eliminate this tradeoff.

### Market Data
BuyerKiosk serves multiple store concepts (CM, PC, OU, SE) each with 20-60 DRS subcategories. Stores typically use 40-70% of available categories. The unused 30-60% creates dropdown noise that this feature addresses.
