# Product Requirements Document
# 045 - Workbook Backstock Management View

## 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

Store employees can manage their backstock inventory directly from the workbook without needing access to the admin panel, enabling faster floor operations and reducing dependency on admin-level users for day-to-day inventory management.

### Problem Statement

Today, backstock management is only available in the admin panel at `/admin/:typeNum/backstock`. This creates several problems:

1. **Access barrier**: Store employees who work the floor and handle bins daily often don't have admin panel access. They must ask a manager or admin to look up bins, perform actions, or print labels on their behalf.
2. **Context switching**: Even for users who have admin access, managing backstock requires leaving the workbook (where they spend most of their shift) and navigating to a completely different interface. This breaks their operational flow.
3. **Workflow fragmentation**: The workbook already has a lightweight "bins to pull" panel, but it only shows a subset of bins needing action. There's no way to search the full inventory, perform mass edits, manage locations/categories, or create new bins from within the workbook.
4. **Underutilization**: Store owners who want their team to actively manage backstock must either grant admin access (which exposes other admin features they shouldn't see) or accept that backstock management will be slow and manager-dependent.

The consequence is that backstock bins go stale, actions aren't recorded promptly, and the inventory health of the store degrades because the tool isn't accessible where the work happens.

### Value Proposition

By embedding the full backstock management experience into the workbook:

- **Zero context switching**: Employees manage bins in the same interface they use all day
- **Broader access**: Any workbook user at a store with the feature enabled can search, filter, and act on bins
- **Faster operations**: Mass edits, label printing, and bin creation happen where the action is, not in a separate admin panel
- **Owner control**: A per-store feature flag lets owners decide if their team needs this capability, with no cost to stores that don't use backstock
- **Real-time collaboration**: Ably-powered live sync means multiple employees see each other's changes instantly, preventing duplicate work on the same bins

## User Personas

### Primary Persona: Store Floor Employee
- **Demographics:** Store team member (all ages), daily workbook user, moderate technical comfort, uses tablets or desktops at the store
- **Goals:** Quickly find bins, record actions (add/remove items), move bins between locations, and keep inventory current during their shift
- **Pain Points:** Currently can't access the backstock management grid; must ask a manager to look things up or perform actions; the small "bins to pull" panel in the workbook doesn't let them search or filter the full inventory

### Secondary Persona: Store Manager / Owner
- **Demographics:** Manager-level or owner-level user, has admin panel access, responsible for inventory health and team productivity
- **Goals:** Empower team to self-serve backstock management; monitor inventory health without being a bottleneck; control which stores have the feature enabled
- **Pain Points:** Gets interrupted by employees who need admin panel access for simple bin lookups; can't delegate backstock management without granting full admin access; wants to turn the feature on/off per store

## User Journey Maps

### Primary User Journey: Floor Employee Managing Bins

1. **Awareness:** Employee opens the workbook for their shift and sees "Backstock" in the sidebar navigation (because the store owner enabled the feature flag)
2. **Consideration:** Employee clicks "Backstock" and sees the familiar Syncfusion Grid with all bins, search bar, and action toolbar - everything they'd see in the admin panel
3. **Adoption:** Employee searches for specific bins by name (or comma-separated names for multiple), selects them, and uses the floating action bar to perform mass edits (e.g., change location after moving bins)
4. **Usage:** Throughout their shift, the employee creates new bins for incoming inventory, records add/remove actions via the manage modal, prints labels, and empties bins that are cleared out. Real-time sync means if a coworker empties a bin, the employee sees it update live.
5. **Retention:** The workbook becomes the single place for all operational work. The employee no longer needs to ask managers for bin lookups or wait for admin panel access.

### Secondary User Journey: Owner Enabling Backstock for the Team

1. **Awareness:** Owner learns (from documentation, onboarding, or admin settings page) that backstock can be enabled in the workbook
2. **Consideration:** Owner evaluates whether their team needs direct backstock access vs. manager-only admin panel access
3. **Adoption:** Owner navigates to the store configuration page in the admin panel, finds the "Workbook Backstock" toggle, and enables it
4. **Usage:** Owner monitors team adoption and inventory health metrics through the admin panel reports (which remain admin-only)
5. **Retention:** Inventory health improves as the team manages bins more proactively; owner keeps the flag enabled

### Edge Journey: Feature Flag is OFF

1. Employee opens the workbook sidebar
2. "Backstock" appears as a disabled/grayed-out nav item with a tooltip: "Contact your admin to enable"
3. Employee understands the feature exists but isn't available for their store
4. No backstock view loads; no additional resources are loaded

## Feature Requirements

### Must Have Features

#### Feature 1: Store-Level Feature Flag
- **User Story:** As a store owner, I want to enable or disable the backstock management view in the workbook on a per-store basis so that I control which stores' teams have direct access.
- **Acceptance Criteria:**
  - [ ] A new boolean flag exists per store controlling workbook backstock visibility
  - [ ] The flag can be toggled from the admin store configuration page
  - [ ] When OFF: sidebar shows disabled "Backstock" nav item with tooltip "Contact your admin to enable"
  - [ ] When ON: sidebar shows active "Backstock" nav item that loads the backstock view
  - [ ] Default value for existing stores is OFF (opt-in model)
  - [ ] Flag changes take effect on next page load (no cache invalidation required)

#### Feature 2: Workbook Backstock View (Full-Page SPA View)
- **User Story:** As a store employee, I want to access a full backstock management grid in the workbook so that I can search, filter, and manage all bins without leaving my operational interface.
- **Acceptance Criteria:**
  - [ ] Accessible via sidebar navigation and direct URL `/:typeNum/workbook/backstock`
  - [ ] Uses SPA navigation (no page reload) consistent with other workbook views
  - [ ] Displays a Syncfusion EJ2 Grid with all active bins for the store
  - [ ] Grid columns match admin panel: Bin Name, Location, On-Site, Main Category, Other Categories, Last Action, Age
  - [ ] Grid supports sorting, column filtering (Excel-style), and pagination (50 rows default)
  - [ ] Quick search input with single-term and comma-separated multi-search support
  - [ ] "Hide Empty Bins" and "Show Hidden Bins" toggle switches
  - [ ] Summary stats cards: Total Bins, On-Site, Off-Site, Average Age
  - [ ] Category badge clicking filters the grid to that category
  - [ ] Responsive layout adapts to tablet and desktop screen sizes
  - [ ] Initial grid load completes within 2 seconds for stores with up to 500 bins
  - [ ] Search results update within 300ms of input (debounced)
  - [ ] Page change/sort/filter operations complete within 500ms

#### Feature 3: Manage Bin Modal
- **User Story:** As a store employee, I want to open a bin and see all its details, perform actions, add notes, and view history so that I can manage individual bins completely.
- **Acceptance Criteria:**
  - [ ] Clicking a bin's manage icon opens a multi-tab modal
  - [ ] Edit tab: change name, location, main category, sub-categories, age date
  - [ ] Actions tab: add/remove/empty actions with employee selector, category change, reset age option
  - [ ] Notes tab: view and edit bin notes
  - [ ] Audit tab: view last audit info, item count, estimated value, record new audit
  - [ ] History tab: view action history for the bin
  - [ ] Save button persists all changes
  - [ ] Hide/Reactivate buttons available based on bin state

#### Feature 4: Mass Edit Floating Action Bar
- **User Story:** As a store employee, I want to select multiple bins and perform bulk actions so that I can efficiently manage inventory during shift work.
- **Acceptance Criteria:**
  - [ ] Floating bar appears at bottom when one or more bins are selected
  - [ ] Shows selection count and breakdown (active vs hidden)
  - [ ] Supports 9 mass actions: Change Location, Empty Bins, Change Category, Change Tags, Hide, Unhide, Print Labels, Update Age Date, Add Notes (Note: individual bin DELETE is available via manage modal inline icon, not via mass edit)
  - [ ] Each action opens a confirmation modal showing affected bins
  - [ ] Supports partial success (some bins succeed, some fail) with appropriate feedback
  - [ ] Double-submit protection on confirm buttons
  - [ ] Selection persists across pagination
  - [ ] Success: toast notification with count of bins affected (e.g., "3 bins moved to Back Room")
  - [ ] Partial failure: toast with success count + error count; failed bins remain selected for retry
  - [ ] Full failure: error toast with message; all bins remain selected

#### Feature 5: Bin Creation
- **User Story:** As a store employee, I want to create new bins directly from the workbook so that I can set up inventory containers on the floor without admin access.
- **Acceptance Criteria:**
  - [ ] "Add Bin" button in the toolbar opens a creation modal
  - [ ] Fields: bin name, location, main category, sub-categories, age date, copy quantity
  - [ ] "Bulk Create" button opens a bulk creation modal with prefix/starting number/quantity
  - [ ] Newly created bins appear in the grid immediately
  - [ ] Label printing triggered on creation (matching admin behavior)

#### Feature 6: Location & Category Management
- **User Story:** As a store employee, I want to manage backstock locations and categories from the workbook so that I can organize inventory without admin access.
- **Acceptance Criteria:**
  - [ ] "Locations" button opens a management modal: list, add, edit, delete locations
  - [ ] "Categories" button opens a management modal: list, add, edit, delete custom categories
  - [ ] POS subcategories displayed in category dropdown (read-only, can't be edited)
  - [ ] Changes to locations/categories reflect immediately in all dropdowns
  - [ ] On-site/off-site toggle available per location

#### Feature 7: Label Printing
- **User Story:** As a store employee, I want to print bin labels from the workbook so that I can label new and existing bins on the floor.
- **Acceptance Criteria:**
  - [ ] Reprint button on individual bin rows opens a reprint modal
  - [ ] Quantity selector (1-10 labels per bin)
  - [ ] Mass print via floating action bar for selected bins
  - [ ] Print jobs created through the same mechanism as admin panel
  - [ ] Success: toast notification confirming print job created
  - [ ] Failure (e.g., print service unavailable): error toast with message; user can retry

#### Feature 8: Real-Time Sync via Ably
- **User Story:** As a store employee, I want to see changes made by my coworkers in real time so that we don't perform duplicate work on the same bins.
- **Acceptance Criteria:**
  - [ ] When a bin is created, edited, deleted, hidden, or unhidden by any user, all other users viewing the same store's backstock view see the change reflected in the grid without manual refresh
  - [ ] Mass edit actions broadcast updates for all affected bins
  - [ ] Sync is scoped to the store (typeNum channel)
  - [ ] If a user has a bin's manage modal open when another user modifies that bin, a visual indicator warns of the change
  - [ ] Connection loss shows a subtle offline indicator; reconnection resyncs the grid

### Should Have Features

#### Feature 9: Admin Settings Toggle UI
- **User Story:** As a store owner, I want a clear toggle on my store configuration page to turn the workbook backstock feature on or off.
- **Acceptance Criteria:**
  - [ ] Toggle appears in the store configuration admin page under a "Workbook Features" section
  - [ ] Toggle shows current state (on/off) with description text
  - [ ] Saving the configuration persists the flag to the database
  - [ ] Change is effective on next workbook page load for that store's users

#### Feature 10: CSV Export
- **User Story:** As a store employee, I want to export the current bin data as a CSV so that I can share inventory snapshots with management.
- **Acceptance Criteria:**
  - [ ] Export button in the toolbar triggers a CSV download
  - [ ] Export respects current filters (if filtering by category, only export filtered bins)
  - [ ] CSV includes: Bin Name, Location, On-Site, Main Category, Other Categories, Age, Last Action

### Could Have Features

#### Feature 11: Workbook Backstock Summary Stats Enhancement
- **User Story:** As a store employee, I want quick health metrics beyond just counts so that I can see at a glance if backstock needs attention.
- **Acceptance Criteria:**
  - [ ] Health score displayed prominently (0-100)
  - [ ] Stale bin count (90+ days) with visual alert if threshold exceeded
  - [ ] "Needs Audit" count if audit tracking is active

### Won't Have (This Phase)

- **Analytics/Reports Dashboard**: The detailed analytics (aging charts, category health scores, location utilization, activity summary) remain admin-panel only. The workbook focuses on operational management, not analytics.
- **Backstock Events**: Seasonal event management stays admin-only. Flagged as a potential future follow-up.
- **Mobile App Integration**: The workbook backstock view is web-only for now. Mobile app backstock (if any) is a separate initiative.
- **Custom permission levels**: All workbook users at a store with the flag enabled can access backstock. No per-user or per-role granularity within the workbook for this phase.
- **Offline mode**: Backstock management requires connectivity. No offline-first capabilities.

## Detailed Feature Specifications

### Feature: Workbook Backstock View (Feature 2 - Most Complex)

**Description:** A full-page SPA view within the workbook that renders the complete backstock bin management grid with search, filtering, mass editing, and all operational capabilities matching the admin panel.

**User Flow:**
1. User clicks "Backstock" in the workbook sidebar
2. System activates the backstock view via SPA navigation (no page reload), updates URL to `/:typeNum/workbook/backstock`
3. System loads bin data and renders the Syncfusion Grid with all active bins
4. User sees summary stats cards (Total Bins, On-Site, Off-Site, Avg Age) and the action toolbar
5. User interacts with the grid: search, sort, filter, select bins, open manage modal, perform actions
6. System persists changes via existing API endpoints and broadcasts updates via Ably
7. Other users viewing the same store's backstock see changes reflected in real time

**Business Rules:**
- Rule 1: The backstock view is only accessible when the store's workbook backstock feature flag is ON
- Rule 2: All workbook users at a flagged-on store have equal access - no role-based restrictions within the workbook for backstock
- Rule 3: The view reuses existing backstock API endpoints (`/api/:typeNum/backstock/*`) - no separate workbook-specific endpoints
- Rule 4: Bin data is scoped to the store's database (typeNum) - users can only see and manage bins belonging to their assigned store
- Rule 5: The grid defaults to showing all active bins sorted by name ascending, with empty bins visible and hidden bins not shown (matching admin defaults)
- Rule 6: Real-time sync is mandatory when the view is active - updates from other users must appear within 2 seconds
- Rule 7: If a user navigates away from the backstock view (to queue, workbook dashboard, etc.) and returns, the grid should reload fresh data

**Edge Cases:**
- Scenario 1: Store has 0 bins → Expected: Grid shows empty state with "No bins yet" message and prominent "Add Bin" button
- Scenario 2: Two users edit the same bin simultaneously → Expected: Last write wins at the API level; Ably sync pushes the latest state to both users' grids. If one user has the manage modal open, they see a "This bin was modified by another user" warning banner
- Scenario 3: Feature flag is turned OFF while a user is on the backstock view → Expected: On next SPA navigation or page load, the view becomes inaccessible and the sidebar item grays out. No mid-session ejection.
- Scenario 4: User with comma-separated search finds some bins but not others → Expected: Found bins are selected and scrolled to; unfound terms shown in a "not found" banner
- Scenario 5: Mass edit fails for some bins but succeeds for others → Expected: Success toast for succeeded bins, error toast for failed bins, failed bins remain selected for retry
- Scenario 6: Network connection lost during grid use → Expected: Ably shows offline indicator; actions attempted while offline show error; reconnection triggers grid data refresh
- Scenario 7: User clicks disabled "Backstock" nav item (flag OFF) → Expected: Nothing happens; tooltip shows "Contact your admin to enable"
- Scenario 8: Store has 500+ bins → Expected: Grid paginates at 50 rows; search and filters work performantly; no significant load time increase
- Scenario 9: User navigates directly to `/:typeNum/workbook/backstock` but flag is OFF → Expected: Redirect to workbook dashboard or show "Feature not enabled" message
- Scenario 10: API returns 403 for a workbook user (unexpected permission issue) → Expected: Show "Unable to load backstock data. Please contact your administrator." error state with retry button
- Scenario 11: Bin created/modified in the admin panel while workbook is open → Expected: Change is NOT pushed via Ably (admin doesn't publish). Workbook user sees the update on next view load or manual page refresh. Acceptable consistency trade-off for this phase.
- Scenario 12: Print service fails (printer offline, service error) → Expected: Error toast "Print job failed. Please try again or check printer connection." Print button re-enabled for retry.
- Scenario 13: User deletes a bin via manage modal inline delete icon → Expected: Confirmation dialog ("Are you sure you want to delete this bin? This cannot be undone."); on confirm, bin removed from grid and Ably event published; on cancel, no action
- Scenario 14: Audit tab opened but audit tracking is not active for the store → Expected: Audit tab still visible but shows "Audit tracking is not configured for this store" with fields disabled

### Feature: Real-Time Sync (Feature 8)

**Description:** All backstock mutations broadcast via Ably so multiple employees see live updates.

**User Flow:**
1. Employee A empties Bin #5 via the manage modal
2. System saves the action via API and publishes an Ably event on the store's channel
3. Employee B, viewing the same store's backstock grid, receives the event
4. Employee B's grid updates Bin #5's row in-place (last action, category change, etc.) without a full refresh

**Business Rules:**
- Rule 1: Events are published on channel `backstock:{typeNum}` (e.g., `backstock:pc00`)
- Rule 2: Event types: `bin:created`, `bin:updated`, `bin:deleted`, `bin:hidden`, `bin:unhidden`, `bins:mass-updated`
- Rule 3: Events include the full updated bin object(s) so receivers can update their grid without a separate API call
- Rule 4: Events are only published for mutations made through the workbook backstock view (admin panel mutations do not need to sync to workbook in this phase)
- Rule 5: The manage modal should check for stale data on save (optimistic concurrency) - if the bin was modified by another user since it was opened, warn before overwriting

**Edge Cases:**
- Scenario 1: Ably connection fails → Expected: Subtle "offline" indicator; grid continues to work but doesn't receive live updates; manual refresh still works
- Scenario 2: Ably event arrives for a bin not in the current filter view → Expected: Event is processed silently (updates the underlying data) but row doesn't appear unless filters change
- Scenario 3: Rapid successive events for the same bin → Expected: Each event replaces the previous state; no race conditions in grid rendering

## Success Metrics

### Key Performance Indicators

- **Adoption:** 50%+ of stores with the flag enabled have at least one non-admin user using the workbook backstock view within 30 days of enablement
- **Engagement:** Average of 5+ backstock actions per store per day through the workbook (for flagged-on stores)
- **Quality:** Error rate for backstock API calls from the workbook is <1%; real-time sync latency is <2 seconds for 95th percentile
- **Business Impact:** 20% reduction in stale bins (90+ day age) at stores that enable the feature, measured 60 days after enablement

### Tracking Requirements

| Event | Properties | Purpose |
|-------|------------|---------|
| `workbook_backstock_viewed` | `typeNum`, `userId`, `binCount` | Track view adoption per store |
| `workbook_backstock_search` | `typeNum`, `searchType` (single/comma), `resultCount` | Track search usage patterns |
| `workbook_backstock_action` | `typeNum`, `userId`, `actionType`, `binCount`, `isBulk` | Track action frequency and types |
| `workbook_backstock_bin_created` | `typeNum`, `userId`, `isBulk`, `quantity` | Track bin creation from workbook |
| `workbook_backstock_export` | `typeNum`, `userId`, `format`, `rowCount` | Track export usage |
| `workbook_backstock_flag_toggled` | `typeNum`, `adminUserId`, `newValue` | Track feature enablement |
| `workbook_backstock_ably_sync` | `typeNum`, `eventType`, `latencyMs` | Monitor real-time sync health |
| `workbook_backstock_error` | `typeNum`, `userId`, `endpoint`, `errorCode` | Track error rates |

---

## Constraints and Assumptions

### Constraints
- Must reuse existing backstock API endpoints - no new endpoint logic for CRUD operations
- Feature flag pattern must follow established convention (TINYINT column on `stores` table, `Store::getFeatureFlag()`)
- Real-time sync must use existing Ably infrastructure
- Must work on the same browsers/devices the workbook already supports (Chrome, Safari, tablets)
- Migration system must be used for any database changes (no manual SQL)
- Syncfusion EJ2 Grid must be used (per CLAUDE.md preference for Syncfusion components)

### Access Control Model (Validated)
The workbook backstock view uses a two-layer access control model:
1. **Feature Flag Gate**: Store must have `workbook_backstock_enabled` flag ON (checked in template rendering and route handler)
2. **Store Group Check**: User must pass `checkStoreGroup($typeNum)` (checked on every API call)

**API Endpoint Compatibility (Verified):** The existing `/api/:typeNum/backstock/*` endpoints use inconsistent auth - most only check store group membership, not `uri_backstock` permission. This means workbook users can already call these endpoints. No API changes are needed for authorization. The admin page route (`/admin/:typeNum/backstock`) checks `uri_backstock` permission to render the HTML page, but the API endpoints themselves do not.

**Note:** The inconsistent auth on the admin-level API endpoints is a pre-existing condition. This spec does not change that behavior, but the SDD should note it as a future security hardening opportunity.

### Assumptions
- Ably channel infrastructure can handle the additional message volume from real-time backstock sync
- Store owners will enable the flag themselves once the admin toggle is available (no bulk enablement needed initially)
- Label printing infrastructure works the same regardless of whether triggered from admin or workbook
- Bins created/modified in the admin panel while workbook is open will appear on next view load or manual refresh (admin mutations do not trigger Ably sync in this phase; this is an acceptable consistency trade-off)
- Ably event payloads for mass updates will be chunked or summarized if affecting 50+ bins to avoid oversized messages

## Risks and Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Performance degradation with 500+ bins on workbook load | Medium | Medium | Use same pagination + lazy-load pattern as admin; consider API-loaded data vs server-rendered |
| Ably message volume spikes during busy periods | Low | Low | Rate-limit sync events (debounce mass updates); Ably plan covers current store count |
| Confusion between admin backstock and workbook backstock | Medium | Medium | Clear documentation; workbook version is labeled "Backstock" not "Backstock Admin"; feature parity reduces confusion |
| Users performing destructive actions without understanding | Medium | Low | Confirmation modals for all destructive actions (delete, empty, hide); same UX patterns as admin |
| Feature flag complexity as more flags are added | Low | Medium | Follow established flag convention; consider future admin "Feature Flags" settings section |
| Concurrent edit conflicts between workbook and admin panel users | Medium | Low | Ably sync (workbook side); admin panel users doing edits is lower frequency; last-write-wins is acceptable |
| Ably payload size for mass updates | Medium | Medium | Mass updates affecting 50+ bins should use summary events (list of IDs + action type) rather than full bin objects; receivers fetch updated data via API |
| Data inconsistency between admin and workbook | Low | Medium | Admin mutations don't trigger Ably sync; workbook reloads fresh data on each view activation (Rule 7); acceptable trade-off for this phase |

## Open Questions

All questions resolved during requirements gathering:

- [x] Full page view vs panel? → Full page SPA view at `/:typeNum/workbook/backstock`
- [x] Feature parity scope? → Full parity with admin bins management (not analytics/reports)
- [x] Who can access? → All workbook users when store flag is ON
- [x] API strategy? → Reuse existing admin endpoints
- [x] Chart library? → Syncfusion (for any charts/visualizations needed)
- [x] Flag OFF behavior? → Disabled nav item with tooltip
- [x] Flag toggle location? → Admin store configuration page
- [x] Events page? → Not in this phase
- [x] Real-time sync? → Yes, via Ably
- [x] Default flag value? → OFF for existing stores (opt-in)

---

## Supporting Research

### Competitive Analysis
Not applicable - this is an internal platform feature. The competitive advantage is operational efficiency for store teams vs. the current admin-only access model.

### User Research
Based on direct product owner input:
- Store employees regularly need to search and manage bins but lack admin access
- The existing "bins to pull" workbook panel is too limited for full inventory management
- Store owners want to control feature availability per store
- Real-time sync is valued for team coordination during shift work

### Market Data
Not applicable - this is a B2B internal tool enhancement. Value is measured in operational efficiency (reduced stale inventory, faster bin management, fewer admin interruptions).
