Marketplace Project: Browsing the Marketplace
Learning Objectives
- You can organize a read interface into components and explicit network states.
- You can transform category relationships into recursive navigation.
- You can support detail links that work independently of earlier browser actions.
- You can test those behaviors while preserving the accepted Part 1 marketplace project.
We have practiced components, state, requests and navigation in smaller examples.
Now continue in your local marketplace repository (marketplace/) from Part 1. Its six accepted
milestones are the starting point; this part adds milestones 7-12. Do not replace
the marketplace repository with the practice application or copy laboratory routes into it.
Each card contains the contract, checks and submission instructions for one
increment. Fetch the next milestone as instructed and keep working on master.
Most milestone branches are comparison references containing the preceding accepted
increment, not the new answer. Milestone 11’s handout marks the exception: its
branch carries two contributed server modules that you integrate into master.
Use compose.yaml and compose.test.yaml with a separate marketplace test
Compose project name. The chapter examples use wsd-practice-test;
wsd-marketplace-test is an example for the marketplace repository, not a shared name.
The read contract stays consistent: listing IDs and related IDs are positive integers, and prices are integer euro cents. Each listing includes its actual seller and category names. Collection reads are capped at 100; filtering here covers the loaded collection, not an unbounded server search.
Listing components and read modules
First separate obtaining data from displaying one listing. Keep the existing root heading, counter and todo controls. The card receives data, and its owner performs the collection request. Milestone 7 also makes the runtime response checks explicit.
Marketplace milestone 7: read modules and listing cards
0 / 35 points
Continue the marketplace project
Continue in the local marketplace repository after milestone 6 passes. Run
git fetch origin and keep working on master. There is no new marketplace repository.
The reference branch contains the preceding milestone, not the solution to this one.
Inspect or merge it only when you need to recover a known baseline.
Objective
Refactor the existing listing view into a read module and a presentation component. Do not replace the marketplace project with the neutral practice application.
Create client/src/lib/marketplace/marketplace-api.ts and export Listing,
Category, decodeListing, getListings, getCategories, and getListing.
Listing retains id, title, description, startingPrice, sellerId,
sellerName, categoryId, and categoryName; Category has id, parentId,
name, and slug. Prices are whole euro cents. IDs are positive PostgreSQL
integers. The decoder checks these fields at runtime and ignores additional
fields rather than casting an unknown response. getCategories must likewise
validate that the response is an array and that every category has the stated
fields, including a positive integer ID and a null or positive integer parent ID.
List operations return arrays; the detail operation returns one listing. Each
accepts an optional abort signal, passes it to fetch, checks the HTTP status,
and uses the existing configured public API base URL. For an HTTP failure,
reject with an Error whose message includes the status. The detail operation
will be used after the supplied bridge in milestone 11.
Create client/src/lib/marketplace/ListingCard.svelte with one listing prop.
Render a list item containing
a heading with a title link to /listings/<id>, plus Seller: name,
Category: name, and Starting price: €7.25 for an amount of 725 cents.
Use the supplied relationship names, not a guessed parent category. The detail
page need not work yet.
Create client/src/lib/marketplace/ListingsBrowser.svelte; let it own the
collection request and use one card per row. Modify the existing
client/src/lib/ListingList.svelte so it remains a small wrapper around the new
browser component and the existing root page still works.
Keep Campus Marketplace, Load listings, the Counter and Todos sections,
and their original controls. Full empty/error/retry behavior is the next milestone.
The supplied public observations use Jamie and Noor, but the component check uses unfamiliar data. Do not hardcode a title, category, seller, ID, or price.
Test and submit
Use the two Compose files and an unused, separate Compose test project name. Replace
wsd-marketplace-test in the example commands with that name. During an
increment, run the client test command first; it is the focused subsystem suite
for this milestone. The complete sequence below is useful at
the part acceptance checkpoint; do not repeat an unrelated build after every small
edit. Never erase your development database merely to run a test. All shell
commands belong to the marketplace repository, not the practice application.
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test# Optional local type diagnostics; not graded in this milestone.docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task checkdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task builddocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm api deno task testdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-testsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml downRun suites sequentially. If you reuse an already-running test API after editing its
source, restart it: unlike the development service, it does not watch files.
Do not commit real secrets, generated builds, test results, or node_modules.
Inspect git diff, stage the specific source, migration and test files you changed,
commit, and run git push origin master. The grader uses trusted runtime
configuration; submitted Docker or package scripts are not executed as grading code.
Type checking is optional in this milestone and does not affect points. The grader assesses executable tests and application behavior.
Points
- 20 points: Render varied listing relationships, euro-cent price, and detail link.
- 15 points: Validate listing/category responses and preserve the configured, status-checked, abortable read contract.
Preserving the previously accepted read paths, counter and todo behavior, migration history, and a buildable client are readiness conditions. These conditions do not re-award points from earlier milestones.
Network states and recovery
Part 1 established a successful read. Now distinguish pending, empty and failed reads, clear stale rows, and recover with a later request. Test transitions within one mounted view rather than assuming isolated screenshots establish recovery.
Marketplace milestone 8: loading, empty results and recovery
0 / 30 points
Continue the marketplace project
Continue in the local marketplace repository after milestone 7 passes. Run
git fetch origin and keep working on master. There is no new marketplace repository.
The reference branch contains the preceding milestone, not the solution to this one.
Inspect or merge it only when you need to recover a known baseline.
Objective
Extend ListingsBrowser.svelte with explicit idle, loading, ready, and error
states. Keep Load listings available for a new request, including while another
read is pending. Display Loading listings… in an element with role="status"
while pending,
No listings available. for a successful empty array, and an alert beginning
Could not load listings. for a failure. Include the HTTP status for an HTTP
failure and include the thrown Error.message for a network failure.
A new request clears previously shown rows. An empty response or failure must not leave old cards visible. A successful retry clears the old error. Abort obsolete requests, invalidate their generation, and cancel the outstanding read when the component is removed. A late success or rejection must not overwrite a newer view.
Use controlled response sequences when testing: data→empty→data and data→HTTP failure→network failure→successful retry. Do not assume that checking four separately mounted components establishes all those transitions.
Test and submit
Use the two Compose files and an unused, separate Compose test project name. Replace
wsd-marketplace-test in the example commands with that name. During an
increment, run the client test command first; it is the focused subsystem suite
for this milestone. The complete sequence below is useful at
the part acceptance checkpoint; do not repeat an unrelated build after every small
edit. Never erase your development database merely to run a test. All shell
commands belong to the marketplace repository, not the practice application.
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test# Optional local type diagnostics; not graded in this milestone.docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task checkdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task builddocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm api deno task testdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-testsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml downRun suites sequentially. If you reuse an already-running test API after editing its
source, restart it: unlike the development service, it does not watch files.
Do not commit real secrets, generated builds, test results, or node_modules.
Inspect git diff, stage the specific source, migration and test files you changed,
commit, and run git push origin master. The grader uses trusted runtime
configuration; submitted Docker or package scripts are not executed as grading code.
Type checking is optional in this milestone and does not affect points. The grader assesses executable tests and application behavior.
Points
- 5 points: Clear old rows after an empty result and restore them after another read.
- 15 points: Distinguish HTTP/network failure and recover without stale cards or errors.
- 10 points: Keep only the latest request and cancel obsolete reads.
Preserving the previously accepted read paths, counter and todo behavior, migration history, and a buildable client are readiness conditions. These conditions do not re-award points from earlier milestones.
Category relationships
The API gives us flat parent references. Turn them into a nested structure without assuming that parents arrive first, then identify a selected branch’s descendants. This data transformation supplies the hierarchy that the recursive component renders.
The result must preserve root and sibling input order, support several roots and more than two levels, and leave the source rows unchanged. A child-before-parent case prevents an implementation from treating arrival order as hierarchy. Keep tree construction and descendant traversal as separately testable operations; the exercise asks you to choose and implement an algorithm satisfying those invariants.
Marketplace milestone 9: category relationships as a tree
0 / 25 points
Continue the marketplace project
Continue in the local marketplace repository after milestone 8 passes. Run
git fetch origin and keep working on master. There is no new marketplace repository.
The reference branch contains the preceding milestone, not the solution to this one.
Inspect or merge it only when you need to recover a known baseline.
Objective
Create client/src/lib/marketplace/categories.ts. Export CategoryNode (the
existing category fields plus children), buildCategoryTree(rows), and
descendantIds(node).
Inputs have unique positive IDs, existing parent references, and no cycles.
They may be empty, have several roots, contain more than two levels, and place a
child before its parent. Preserve root and sibling input order. Never mutate the
input array or rows. A leaf has an empty children array. descendantIds returns
the node’s own ID followed by descendants in depth-first sibling order.
For example, input (30→20), (10→null), (20→10), (40→null) has roots 10 and 40;
30 is below 20, below 10. Do not special-case these identifiers.
Create client/src/lib/marketplace/categories.test.ts and add your own Vitest
cases for the stated cases. These tests are local regression evidence and are
returned and reassessed in milestone 12; milestone 9’s points come from the
grader’s independent unfamiliar trees. Defensive detection of invalid graphs is
not required here.
Test and submit
Use the two Compose files and an unused, separate Compose test project name. Replace
wsd-marketplace-test in the example commands with that name. During an
increment, first run the category test directly:
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test src/lib/marketplace/categories.test.tsThe complete sequence below is useful at the part acceptance checkpoint; do not repeat an unrelated build after every small edit. Never erase your development database merely to run a test. All shell commands belong to the marketplace repository, not the practice application.
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test# Optional local type diagnostics; not graded in this milestone.docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task checkdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task builddocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm api deno task testdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-testsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml downRun suites sequentially. If you reuse an already-running test API after editing its
source, restart it: unlike the development service, it does not watch files.
Do not commit real secrets, generated builds, test results, or node_modules.
Inspect git diff, stage the specific source, migration and test files you changed,
commit, and run git push origin master. The grader uses trusted runtime
configuration; submitted Docker or package scripts are not executed as grading code.
Type checking is optional in this milestone and does not affect points. The grader assesses executable tests and application behavior.
Points
- 15 points: Build ordered relationships for empty and parent-last multi-level input without mutation.
- 10 points: Collect the selected category and all of its descendants.
Preserving the previously accepted read paths, counter and todo behavior, migration history, and a buildable client are readiness conditions. These conditions do not re-award points from earlier milestones.
Recursive category navigation
Use the recursive outline pattern from Chapter 2.5 to render native category buttons. Selecting a parent includes listings in its descendants. Keep selection separate from the underlying loaded collection so All categories can restore it.
Marketplace milestone 10: recursive navigation and filtered browsing
0 / 40 points
Continue the marketplace project
Continue in the local marketplace repository after milestone 9 passes. Run
git fetch origin and keep working on master. There is no new marketplace repository.
The reference branch contains the preceding milestone, not the solution to this one.
Inspect or merge it only when you need to recover a known baseline.
Objective
Create client/src/lib/marketplace/CategoryBranch.svelte and
client/src/lib/marketplace/CategoryNavigation.svelte. Use the category helpers
in a recursive CategoryBranch and a small CategoryNavigation. Render native
category buttons in nested lists inside navigation named Categories. Use
aria-pressed to indicate the selected button; do not claim the ARIA tree
interaction pattern. A branch receives node, selected (an ID or null), and an
onselect: (id: number) => void callback.
Modify the existing client/src/lib/ListingList.svelte and
client/src/lib/marketplace/ListingsBrowser.svelte. Connect navigation and
browsing through their common ListingList owner. CategoryNavigation receives
onselect: (ids: number[] | null) => void; invoke it with the selected node’s
descendant IDs, or with null for All categories. ListingsBrowser accepts
selectedIds: number[] | null, defaulting to null.
Selecting a category displays rows assigned to that category or any descendant.
All categories restores the full loaded collection. Retain the underlying
collection; filtering must not destroy it. Empty filtered results display
No listings match this category., not an API-failure message.
Fetch categories once when navigation mounts. Show Loading categories… in
an element with role="status" inside the category navigation while pending.
A failed category read shows an alert and Retry categories. Include the HTTP
status for an HTTP failure and the thrown Error.message for a network failure.
Keep the listing read independently usable. Cancel obsolete category reads.
Continue to handle the listing response sequences required by milestone 8.
The sample Electronics parent contains Computers and Adapters. Tests use different categories and deeper trees, so a hardcoded two-level menu is insufficient.
Test and submit
Use the two Compose files and an unused, separate Compose test project name. Replace
wsd-marketplace-test in the example commands with that name. During an
increment, run the client test command first; it is the focused subsystem suite
for this milestone. The complete sequence below is useful at
the part acceptance checkpoint; do not repeat an unrelated build after every small
edit. Never erase your development database merely to run a test. All shell
commands belong to the marketplace repository, not the practice application.
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test# Optional local type diagnostics; not graded in this milestone.docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task checkdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task builddocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm api deno task testdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-testsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml downRun suites sequentially. If you reuse an already-running test API after editing its
source, restart it: unlike the development service, it does not watch files.
Do not commit real secrets, generated builds, test results, or node_modules.
Inspect git diff, stage the specific source, migration and test files you changed,
commit, and run git push origin master. The grader uses trusted runtime
configuration; submitted Docker or package scripts are not executed as grading code.
Type checking is optional in this milestone and does not affect points. The grader assesses executable tests and application behavior.
Points
- 25 points: Render and select nested categories with descendant filtering and cancel the category read when navigation is removed.
- 15 points: Recover a failed category read, keep listing reads independent, distinguish empty filtered results, and restore the loaded collection.
Preserving the previously accepted read paths, counter and todo behavior, migration history, and a buildable client are readiness conditions. These conditions do not re-award points from earlier milestones.
Independently addressable listing details
Part 1 did not include a detail endpoint. Before beginning this milestone, open
its exercise handout. The exercise makes two new server modules available through
Git as work contributed by someone else. Follow the handout’s instructions to
inspect and fast-forward to that contribution before you edit the milestone. The
incoming commit does not replace an existing project file. After receiving it,
register its router in api/src/app.ts; the rest of the milestone can then
concentrate on browser navigation.
A detail read queries its ID independently of the collection cap. The browser page must work after direct navigation or refresh, distinguish a missing record, and cancel obsolete reads. Do not depend on the last card someone clicked.
Marketplace milestone 11: deep links and independent detail reads
0 / 30 points
Receive the contributed server modules
Continue in the local marketplace repository after milestone 10 passes. Before
editing milestone 11, make sure git status --short is empty. Then fetch, inspect,
and fast-forward your master branch to the contributed server modules:
git fetch origingit diff --stat HEAD..origin/milestone-11git diff HEAD..origin/milestone-11 -- \ api/src/marketplace/listing-detail-repository.ts \ api/src/marketplace/listing-detail-routes.tsgit merge --ff-only origin/milestone-11The branch is based on the remote master present when the contribution is
released after milestone 10, and it adds only those two new files. If the
fast-forward is refused because you already made a local commit, do not reset or
overwrite that work. Verify that the two paths do not exist locally, then replay
the new-file commit with git cherry-pick origin/milestone-11.
Register the contributed route
The Part 1 API had no detail route. The contributed files supply an independent
detail query and a Hono router without replacing files you have already edited.
Register the router in api/src/app.ts by importing listingDetailRoutes from
./marketplace/listing-detail-routes.ts and mounting it with
app.route("/api/listings", listingDetailRoutes). Keep all earlier routes and
imports. The supplied route reads independently of the 100-row collection cap;
invalid IDs return 400 and missing records return 404.
Objective
Create client/src/routes/listings/[id]/+page.svelte and
client/src/lib/marketplace/ListingDetail.svelte. Use the current route parameter;
key the detail component by it so one route cannot retain another route’s data.
ListingDetail takes id: string, validates a positive PostgreSQL integer before
requesting it, and cancels the request when removed.
Show Loading listing… in an element with role="status" while loading;
show a heading Listing not found for 404; show an alert
Could not load listing. with the status/error for other
failures. Invalid parameters include Invalid listing ID in the alert. On
success, display a heading with the title, the description, labelled seller and
category, and the formatted starting price. Include Back to listings, a real
link to /.
A direct visit and browser refresh must work without first selecting a card.
The browser route is /listings/<id>; the JSON API route is /api/listings/<id>.
They are not interchangeable. Use explicit browser fetch, not server actions.
Test and submit
Use the two Compose files and an unused, separate Compose test project name. Replace
wsd-marketplace-test in the example commands with that name. During an
increment, run the browser test command first when changing the detail flow, or
the API test command first when changing route registration. The complete
sequence below is useful at
the part acceptance checkpoint; do not repeat an unrelated build after every small
edit. Never erase your development database merely to run a test. All shell
commands belong to the marketplace repository, not the practice application.
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test# Optional local type diagnostics; not graded in this milestone.docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task checkdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task builddocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm api deno task testdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-testsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml downRun suites sequentially. If you reuse an already-running test API after editing its
source, restart it: unlike the development service, it does not watch files.
Do not commit real secrets, generated builds, test results, or node_modules.
Inspect git diff, stage the specific source, migration and test files you changed,
commit, and run git push origin master. The grader uses trusted runtime
configuration; submitted Docker or package scripts are not executed as grading code.
Type checking is optional in this milestone and does not affect points. The grader assesses executable tests and application behavior.
Points
- 20 points: Load every required field at a direct address, reload it, and cancel the detail read when returning to the marketplace.
- 10 points: Distinguish missing records, malformed route parameters, and other HTTP failures.
Preserving the previously accepted read paths, counter and todo behavior, migration history, and a buildable client are readiness conditions. These conditions do not re-award points from earlier milestones.
Regression tests and Part 2 acceptance
Finally, protect category construction, a changing component view and the browser navigation path. Keep Part 1’s relationship tests and original interactions. The final card checks both your evidence and the cumulative read-only marketplace project.
Marketplace milestone 12: Part 2 regression evidence and acceptance
0 / 40 points
Continue the marketplace project
Continue in the local marketplace repository after milestone 11 passes. Run
git fetch origin and keep working on master. There is no new marketplace repository.
The reference branch contains the preceding milestone, not the solution to this one.
Inspect or merge it only when you need to recover a known baseline.
Objective
Keep the existing Part 1 tests. Review and extend the existing
client/src/lib/marketplace/categories.test.ts, and create the other two
student-owned test files at the exact paths below:
client/src/lib/marketplace/categories.test.ts: empty input, parent-last input, several roots and a third level; descendants include the selected node.client/src/lib/marketplace/marketplace-view.test.ts: a card with unfamiliar values and at least one data→failure→retry sequence in a single mounted view.e2e-tests/tests/student_browse.spec.ts: load listings, select Electronics, locate its Computers listing USB-C dock, follow its detail link, verify the seller and description, and reload the detail URL. Add a missing-record case.
Obtain IDs from links or API data; do not assume ID 1. Use role/label locators, scoped relationship assertions and web-first waiting. Public data stays below the current cap. A list filter is not a complete server search system.
The grader first runs your tests against a compatible reference. Only after that baseline passes does it award defect-detection credit. The category tests must fail when descendant collection omits children. The component tests must fail when a card displays the category as its seller. The browser test must fail when selecting a parent wrongly excludes child-category listings. A missing dependency or failed application startup is not a detected defect. Independent checks also test your actual cumulative application.
No public deployment, account, bid form, authentication, or typed HTTP client is required. Those belong to later parts. Keep runtime dependencies unchanged.
Test and submit
Use the two Compose files and an unused, separate Compose test project name. Replace
wsd-marketplace-test in the example commands with that name. During an
increment, run the two new focused suites first:
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test src/lib/marketplace/categories.test.ts src/lib/marketplace/marketplace-view.test.tsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-tests npx playwright test tests/student_browse.spec.tsThe complete sequence below is useful at the part acceptance checkpoint; do not repeat an unrelated build after every small edit. Never erase your development database merely to run a test. All shell commands belong to the marketplace repository, not the practice application.
docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task test# Optional local type diagnostics; not graded in this milestone.docker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task checkdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm --no-deps client deno task builddocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm api deno task testdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml run --build --rm e2e-testsdocker compose -p wsd-marketplace-test -f compose.yaml -f compose.test.yaml downRun suites sequentially. If you reuse an already-running test API after editing its
source, restart it: unlike the development service, it does not watch files.
Do not commit real secrets, generated builds, test results, or node_modules.
Inspect git diff, stage the specific source, migration and test files you changed,
commit, and run git push origin master. The grader uses trusted runtime
configuration; submitted Docker or package scripts are not executed as grading code.
Type checking is optional in this milestone and does not affect points. The grader assesses executable tests and application behavior.
Points
- 5 points: Returned category, component and browser tests pass the compatible reference.
- 5 points: Returned category tests reject a descendant helper that omits children.
- 5 points: Returned component tests reject a card with the wrong seller relationship.
- 5 points: Returned browser test rejects a parent filter that omits descendants.
- 20 points: The submitted cumulative application passes independent browsing checks.
Preserving the previously accepted read paths, counter and todo behavior, migration history, and a buildable client are readiness conditions. These conditions do not re-award points from earlier milestones.
No authentication, bid form, typed client or public deployment is required here. Keep the marketplace repository after Part 2 acceptance. In Part 3, you will continue the marketplace project there while preserving its read contract and changing the server implementation.
Check Your Understanding
- Why should a card receive its data instead of requesting the same collection itself?
- How does an empty filtered view differ from a failed API read?
- Why must category construction handle a child appearing before its parent?
- Why can a detail page not rely on searching only the first collection page?
- Which boundary does each of your category, component and browser tests observe?