LAB: Updating Our Spec

A focused workshop for working developers who need to use AI right now, in real projects, under real time pressure.
The first thing we need to do is to ensure we're working in a dedicated branch so we can take small steps and move backwards as needed.
The next thing we need to do is to formalize our spec into its own document, which we'll put in a /docs directory.
Step 1: Creating a Branch to Work In
We have to be particularly disciplined when it comes to working with AI as we're doing. Small steps, frequent Git commits. We always want to be able to go back and redo things if we're not happy with the way they turned out.
To that end, make sure you're repository is ready to go (no pending changes), and you're in the main branch.
If so:
git checkout -b cart
Good to go.
Step 2: Formalizing Our Spec
Next, we need to create a /docs directory for our spec. The first thing we need to decide is if we want one large document, or many smaller ones.
It's been my experience that you can avoid merge conflicts and frustration by going with smaller spec documents. But that depends on how you work at your company.
For instance:
- If you work in sprints or iterations, and you have a large team, it might be more useful to skip the notion of a "spec" and have an iteration document. This is what we used to do on the VS Code team. Our iterations were monthly, and defined what we were working on.
- If you're a medium-sized team, formality might be overkill. Isolating specific chunks of logic might work well in that case. You might have
cart-spec.md,order-processing.md,fulfillment.md, and so on. - If it's just you, and you're building out a side hustle, a single document might be the way to go so you avoid repetition and confusion.
To keep things as simple as possible, we're going with the middle option and starting out with a cart-spec.md.
mkdir docs
touch docs/cart-spec.md
Now let's fill things in.
Step 3: Writing the Spec
As you've been working with markdown in VS Code, you might have seen Copilot trying to "help" from time to time. It can be useful, but it can also be extremely annoying. The team is trying to get the annoyance level dialed in so it's "just right", but it is possible to turn Copilot off entirely for a given file type.
You might have done this, and if you have, turn it back on and reload the editor window (command palette, "Reload Window").

You can turn it back off if you need to when we're done.
At the very top, add the following Markdown and hit return:
<span class="hljs-section"># Shopping Cart Specification</span>
After a second or two, you should see Copilot's "ghost text" pop in some suggestions. These will vary for everyone in the workshop (most likely), but what you see should look something like this:
<span class="hljs-section"># The Shopping Cart Specification</span>
This document outlines the specifications for the shopping cart functionality in our e-commerce application.
<span class="hljs-section">## Functional Requirements</span>
<span class="hljs-bullet">1.</span> <span class="hljs-strong">**Add to Cart**</span>: Customers should be able to add items to their shopping cart.
<span class="hljs-bullet">2.</span> <span class="hljs-strong">**Remove from Cart**</span>: Customers should be able to remove items from their shopping cart.
<span class="hljs-bullet">3.</span> <span class="hljs-strong">**View Cart**</span>: Customers should be able to view the contents of their shopping cart.
<span class="hljs-bullet">4.</span> <span class="hljs-strong">**Checkout**</span>: Customers should be able to proceed to checkout from their shopping cart.
<span class="hljs-section">## Non-Functional Requirements</span>
<span class="hljs-bullet">1.</span> <span class="hljs-strong">**Performance**</span>: The shopping cart operations should be performed within 200ms.
<span class="hljs-bullet">2.</span> <span class="hljs-strong">**Scalability**</span>: The shopping cart should be able to handle up to 10,000 concurrent users.
<span class="hljs-bullet">3.</span> <span class="hljs-strong">**Security**</span>: The shopping cart should comply with the latest security standards to protect customer data.
<span class="hljs-bullet">4.</span> <span class="hljs-strong">**Usability**</span>: The user interface for the shopping cart should be intuitive and easy to navigate.
<span class="hljs-bullet">5.</span> <span class="hljs-strong">**Accessibility**</span>: The shopping cart should be accessible to users with disabilities, following WCAG 2.1 guidelines.
<span class="hljs-bullet">6.</span> <span class="hljs-strong">**Maintainability**</span>: The shopping cart code should be well-documented and easy to maintain.
<span class="hljs-bullet">7.</span> <span class="hljs-strong">**Testability**</span>: The shopping cart code should be easy to test, with automated tests covering all critical functionality.
<span class="hljs-section">## User Stories</span>
<span class="hljs-bullet">1.</span> <span class="hljs-strong">**As a customer**</span>, I want to add items to my cart so that I can purchase them later.
<span class="hljs-bullet">2.</span> <span class="hljs-strong">**As a customer**</span>, I want to remove items from my cart so that I can manage my selections.
<span class="hljs-bullet">3.</span> <span class="hljs-strong">**As a customer**</span>, I want to view my cart so that I can see what I am about to purchase.
<span class="hljs-bullet">4.</span> <span class="hljs-strong">**As a customer**</span>, I want to save my cart for later so that I can return to it at another time.
<span class="hljs-bullet">5.</span> <span class="hljs-strong">**As a customer**</span>, I want to apply discount codes to my cart so that I can save money on my purchases.
If you don't, add the subhead ## Functional Requirements and see if ghost text pops things in for you.
If none of this happened, don't worry, we can have Gemini help us.
Asking Gemini
We'll need to try a few times with this prompt, which is OK as that's the nature of working with AI.
Let's start with a simple request:
Create a shopping cart for the store in markdown.
You should see Gemini try to create a file for you. If not, skip the next part.
We need to tell Gemini that we just want text output, so we'll add that to the end of the prompt:
Create a shopping cart for the store in markdown don't create a file output text only.
You should see something like this, with Gemini being its terse self:

This works, but having functional, non-functional, and user stories is pretty nice. So let's ask for it in a follow up prompt:
divide it into function, non-functional, and user stories
The result is very good and something we can build on top of right away:
Functional Requirements
Properties:
* items: An array of product objects. Each object in the array must include a quantity attribute.
* total: The total price of all items in the cart, calculated in pennies.
* id: A UUID (v4) to uniquely identify the cart instance.
Methods:
* addItem(product, quantity): Adds a given product to the items array. If the product already exists in
the cart, this method updates the existing item's quantity.
* removeItem(product): Removes a given product from the items array.
* updateQuantity(product, quantity): Updates the quantity for a specific product already in the cart. If
the quantity is set to 0, the item is removed.
* getTotal(): Calculates and returns the total price of all items in the cart.
* getCart(): Returns the entire cart object, including id, items, and total.
* clearCart(): Empties the items array.
* checkout(customer): Initiates the order creation process using the cart's contents. If the customer is
not registered, a new customer record is created. Upon successful checkout, the cart is cleared.
Non-Functional Requirements
* Persistence: The shopping cart object is ephemeral and will not be persisted to the database. It exists
only in memory during a user's session.
* Performance: Cart operations, especially getTotal(), must be computationally inexpensive and execute
quickly to ensure a responsive user experience.
* Statelessness: Each cart instance is independent and does not share state with other instances.
User Stories
* As a shopper, I want to add an item to my cart so that I can purchase it later.
* As a shopper, I want to see the total price of the items in my cart so that I know how much I will be
charged.
* As a shopper, I want to remove an item from my cart so that I can decide not to buy it.
* As a shopper, I want to change the quantity of an item in my cart so that I can buy more or fewer of a
single product.
* As a shopper, I want to be able to check out so that I can complete my purchase and create an order.
* As a guest, I want to check out without creating an account so that I can make a purchase quickly.
Let's have Gemini print this out as markdown to our spec file:
replace the contents of @docs/cart-spec.md with the above transform to markdown
Gemini should transform the text to Markdown and update the cart-spec.md file. If it tries to do more than that, just hit escape to stop the process.
A focused workshop for working developers who need to use AI right now, in real projects, under real time pressure.