Use a technical spike to resolve a feasibility question with executable evidence. Use a prototype to examine how people understand and complete a workflow. For a CSV importer, parsing and validation need a spike; choosing columns and recovering from rejected rows need a prototype. Neither result proves the other.
Start with the uncertainty, not the artifact
A small equipment-lending service needs to import an inventory spreadsheet. Staff export CSV files from different spreadsheets, then map their columns to item name, inventory code, and available quantity. The team has two distinct questions: can the chosen parser preserve the data correctly, and can staff understand what will be imported?
This worked project uses a narrow first release: UTF-8 CSV, up to 10,000 inventory rows, a maximum 5 MB file, one header row, and a preview before saving. These are proposed product limits to verify, not published limits of a parsing library. Other encodings and spreadsheet workbook files are outside this release.
A polished upload screen cannot demonstrate that quoted commas or leading zeroes survive parsing. A command-line parser cannot demonstrate that a coordinator understands why a row was rejected. Name both unknowns before deciding whether to run one investigation or two.
| Question | Best first artifact | Evidence to collect |
|---|---|---|
| Can we preserve and validate this CSV within the agreed limits? | Technical spike | Input files, parser configuration, expected rows, actual errors and timings |
| Can staff map columns and correct invalid rows? | Interactive prototype | Task attempts, mapping choices, interpretations, recovery behavior |
| Can this ship reliably? | Integrated implementation and verification | Persistence, authorization, retries, accessibility, supported-browser behavior |
Build a tiny dataset with known answers
Use a file whose content you can inspect, then add larger generated fixtures separately. The header is item_name,inventory_code,quantity. The first data row is "Cable, USB-C",00123,4; the next is Tripod,00456,0; the third is Projector,00789,-2. Keep the quoted comma in the first name and the leading zeroes in every code.
The first two rows should pass the product rules. The third should parse into three fields but fail quantity validation because this service requires a whole number of zero or more. That distinction matters: syntactically valid CSV can still contain invalid inventory data.
Create separate fixtures for an empty file, a missing required column, a duplicate inventory code, a row with an extra field, a quoted line break, and an over-limit file. Decide the expected response before running the parser. A test that only checks “did not crash” can miss silent data changes.
| Input case | Expected result | What it detects |
|---|---|---|
| "Cable, USB-C",00123,4 | Name contains comma; code stays 00123; quantity becomes validated integer 4 | Naive comma splitting or accidental numeric conversion |
| Tripod,00456,0 | Accepted; zero stock is valid | Falsy-value checks rejecting zero |
| Projector,00789,-2 | Parsed, then rejected with a quantity reason | Conflating parsing with business validation |
| Repeated code 00123 | Flag duplicate according to the import policy | Unintended overwrite |
| Quoted line break in a name | One logical data record, not two | Incorrect physical-line counting |
Run a timeboxed technical spike
For a one-day investigation, first confirm the parser behavior on those small fixtures, then inspect error reporting, then run representative larger files on the target device. Save the fixture, browser, configuration, elapsed time, and result together. If the timebox expires with an unresolved question, record it explicitly instead of converting uncertainty into a pass.
Papa Parse is a concrete implementation reference. Its documentation describes header-based results, parser errors, dynamic typing, workers, and streaming callbacks. In this project, keep inventory codes as text and validate quantities deliberately. Automatically turning every numeric-looking field into a number would destroy the meaning of 00123.
Check duplicate headers as well as duplicate row values. Papa Parse documents automatic renaming of duplicated header names, so a product that requires unique columns must inspect that condition rather than assuming the library rejects it. A worker may help responsiveness, but it does not replace testing your validation and preview work on the target device.
| Spike record | Fill with observed evidence |
|---|---|
| Hypothesis | The candidate parser preserves required fields and reports malformed rows within the chosen product limits |
| Fixtures | [Exact small CSV files] plus [10,000-row and over-limit fixtures] |
| Environment | [Device, browser, library version, configuration] |
| Acceptance | All expected data outcomes match; over-limit files rejected clearly; measured responsiveness meets the team’s agreed threshold |
| Results | [Actual row comparison, errors, elapsed times, and UI responsiveness observations] |
| Decision | [Use candidate / change approach / investigate further] with the unresolved question |
Prototype the decision staff actually make
Now build five states: choose file, map columns, preview valid and invalid rows, review the import count, and view the saved result. The prototype can use the tiny fixture and simulated results. Its job is to reveal whether people understand the decision; connect it to the real parser later.
Give a staff member this task: “Add the items from this export. Make sure the inventory codes remain correct, and do not import records with an invalid quantity.” Avoid telling them which controls to click. Observe whether they notice 00123, understand zero stock, and recognize why Projector is excluded.
Use a concrete first-release policy: invalid rows block the import until corrected in the source file and uploaded again. This is simpler to explain than silently importing only some rows. If partial import is important to your users, prototype its count, exclusions, retry behavior, and duplicate handling as a separate decision.
| Screen | What the user must understand | Check during the session |
|---|---|---|
| Mapping | Which source column becomes inventory code | Does 00123 remain visible as text? |
| Preview | Two valid rows; one invalid quantity | Can the person identify Projector and explain the problem? |
| Blocked review | Nothing has been saved yet | Do they know to correct the file and upload again? |
| Ready review | All rows valid; exact count ready to import | Can they explain what the final button will do? |
| Result | Confirmed saved count and any remaining problem | Can they distinguish success from a pending request? |
Combine the evidence without overstating it
Suppose the spike preserves codes correctly but prototype participants interpret the preview as already saved. The next action is to change status and commitment cues; replacing the parser would not address the observed problem. Conversely, an easy-to-understand preview cannot compensate for codes losing leading zeroes.
Before implementation, write a short conclusion for each investigation. A spike conclusion might say which fixtures passed and which performance question remains open. A prototype conclusion should name observed behavior and the proposed interaction change, without turning a few sessions into a population success rate.
The integrated release still needs checks for repeated submissions, persisted results, access control, and failed requests. Keep experimental code only if it meets the production requirements. A spike’s value is the decision it enables; a prototype’s value is what it reveals about the workflow.
| Reusable brief | Complete before starting |
|---|---|
| Unknown | [Specific feasibility or understanding question] |
| Artifact | [Executable experiment or interactive flow] |
| Inputs | [Fixtures or participant task and context] |
| Pass / decision rule | [Expected behavior or observation that changes the decision] |
| Timebox and owner | [Time available] / [person responsible] |
| Report | [Evidence] / [decision] / [remaining uncertainty] / [next action] |
