Jeśli można - prośba o feedback ad. mój proces developmentu. Przepraszam jeśli to nieodpowiedni dział.
Cel: feedback pod uczenie się -> poprawienie swojego zrozumienia.
Mój ogólny workflow: PRD feature -> design/mock ui/ux -> Techniczny Design Rozwiązania -> Plan testów -> Testy -> Implementacja -> Green/Refactor jeśli potrzebny. Jest w tym coś niepotrzebnego/coś słabego?
- PRD. Na ile jest profesjonalny/solidnie zrobiony? 1-10
- Organizacja testów (data layer -> unit testy, view layer -> integration test, + happy path e2e). Na ile profesjonalnie/dobrze? 1-10
- Chciałbym wrzucić całe testy pod feedback ale nie chce spamować. Na ile to wygląda profesjonalnie/solidnie z 2 wyrywków, na ile taki pattern jest dobry/solidny? 1-10
Zakres: globalny koszyk. (stronę koszyka oddzieliłem na osobny produkt feature, tak samo jak checkout queue/checkout flow/adres/shipping/stripe/return page)
PRD:
Goal: capture accurate minimalest requirements for coherent, intuitive, simple user see -> actions -> goal experience
Criteria: 0 unnecessary verbiage, 0 unnecessary characters
Feature: Non-Local Basket
Perspective: User interacting with basket controls across any product page
1. Objective
Users add, modify, and remove basket items from any page with persistent state across sessions and tabs.
2. Scope Boundaries
In Scope:
- User perspective - what user sees, can do and experiences
- Global basket state management
- Product controls (add, increment, decrement, remove)
- Persistence across page refreshes
- Cross-tab synchronization
- Header badge count display
- localStorage storage
Out of Scope:
- Anything outside user perspective - what happens under the hood, how it's implemented, etc.
- Basket page rendering
- CMS inventory sync
- Stock availability display
- Checkout process
- Payment processing
3. Requirements & Definition of Done (DoD)
[ ] DoD [1]: When I add a product, I want it in my basket
- When I go to any product page, I see add to basket button
- I click add button
- Product appears in basket with quantity 1
- Header badge (basket button) count increments
[ ] DoD [2]: When I increment quantity, I want count updated up to available stock
- When I go to any product page with item in basket, I see increment button
- I click increment button
- Item quantity increases by 1
- Header badge count updates by 1 increment
- When I try to see how far I can increment, I see that at some point increment button is disabled - I reached available stock limit
[ ] DoD [3]: When I decrement quantity, I want count updated
- When I go to any product page with item in basket, I see decrement button
- I click decrement button
- Item quantity decreases by 1
- Header badge count updates by 1 decrement
[ ] DoD [4]: When I decrement to zero, I want item removed
- When I go to any product page with item quantity 1, I see decrement button
- I click decrement button
- Item removes from basket
- Header badge count updates
[ ] DoD [5]: When I refresh page, I want basket preserved
- When I go to any page with items in basket
- I refresh page
- Basket items remain with same quantities
- Header badge count remains correct
[ ] DoD [6]: When I open new tab, I want basket synced
- When I go to any page with items in basket in tab A
- I open same site in new tab B
- I see that basket count badge is up to date on tab B
- I add/remove/increment/decrement a few products in tab B
- I go back to tab A and see that basket count badge is up to date on tab A after my changes in tab B
[ ] DoD [7]: When I click basket button, I want to go to basket page
- When I go to any page, I see basket button in header
- I click basket button
- I navigate to /basket page
Screenshot drzewka plików i folderów:

Diagram:

Wyrywek z unit testów:
describe('when decrementing quantity to 0', () => {
it('removes item from basket items array', () => {
// ARRANGE - setup test state with product quantity = 1
const productId = 'product-1'
useBasketStore.getState().addProduct(productId, 100, 10)
// ACT - call decrementQuantity with productId
useBasketStore.getState().decrementQuantity(productId)
// ASSERT - verify item removed from items array
const state = useBasketStore.getState()
expect(state.items).toHaveLength(0)
})
})
Wyrywek z integration testów:
describe('when user clicks add button (product page)', () => {
it('hides add button and renders increment/decrement buttons', () => {
// ARRANGE - setup test state with rendered BasketControls, product not in basket
const productId = 'product-1'
const displayPriceAtAdd = 100
const availableStockAtAdd = 10
render(
<BasketControls
productId={productId}
displayPriceAtAdd={displayPriceAtAdd}
availableStockAtAdd={availableStockAtAdd}
isBasketPage={false}
/>
)
// ACT - trigger user click on add button
act(() => {
screen.getByTestId('add-to-basket-product-1').click()
})
// ASSERT - verify add button no longer renders
expect(screen.queryByTestId('add-to-basket-product-1')).not.toBeInTheDocument()
// ASSERT - verify increment/decrement buttons render
expect(screen.getByTestId('increment-product-1')).toBeInTheDocument()
expect(screen.getByTestId('decrement-product-1')).toBeInTheDocument()
})
});