Project Management & User Stories - FactoriaF5-Asturias/project-p5-digital-academy-team1-restaurant-frontend GitHub Wiki
This project was managed using the Agile methodology following the Scrum framework. We used Jira as our central project management tool to plan, track, and organize our development tasks across 2 sprints.
👥 Scrum Team Roles & Structure
We operated as a fully cross-functional Scrum team, ensuring clear ownership and smooth collaboration between design, management, and technical execution:
- Development Team (7 Developers total):
- Front-End Team: 3 Developers (including our Scrum Master and Product Owner roles)
- Back-End Team: 4 Developers
⚙️ Our Scrum Process
We broke our development down into 2 Sprints. To keep the Front-End and Back-End teams aligned and handle dependencies smoothly, we practiced the standard Scrum workflow:
- Sprint Planning: Led by the Product Owner to define the goal of the sprint and select the highest priority User Stories.
- Daily Stand-ups: Facilitated by the Scrum Master to sync on daily progress and immediately flag blockers between the front-end and back-end codebases.
- Sprint Review & Retrospective: Evaluated the working software at the end of the sprint and adjusted our processes to work faster and cleaner in the next cycle.
Backlog organization
Each user story was split into two technical stories so both teams could work in parallel:
GSB-xx— Backend story (endpoint, validation, persistence).GSF-xx— Frontend story (view, components, state, API connection).
When a backend endpoint was not ready yet, the frontend was built against a documented mock with the same response shape, and reconnected to the real API as soon as it was published.
Sprint goals
| Sprint | Goal | Epics closed |
|---|---|---|
| Sprint 1 | A complete and demonstrable dine-in order cycle: view the menu → add to cart → pay → kitchen prepares it — without requiring a user account | Header, Footer, Menu & Order, Cart & Checkout (dine-in), Kitchen, Test coverage setup |
| Sprint 2 | Everything that depends on an account: home delivery, exclusive offers, profile, order history, delivery drivers and administration | Accounts & Profile, Delivery, Administration |
- Jira Board Note: Because our official Jira project is private, the screenshots below serve as visual documentation of our project tracking, active sprints, and task breakdown.
1. Jira Timeline
User Stories
To demonstrate how our Scrum process translated into practice, this section provides concrete examples of User Stories managed within Jira from a frontend perspective. Each example shows how real user requirements were broken down into technical tasks and how our team implemented the solution.
Example 1: Frontend - Manage products in the cart
-
The User Story: "As a customer, I want to add, remove and change the quantity of the products in my cart, So that I can review my order before confirming it."
-
Acceptance Criteria:
- Given that I am on the menu, when I add a product, then it appears in the cart and the header badge shows the number of items.
- Given that a product is already in the cart, when I add it again, then its quantity increases instead of creating a new line.
- Given that a product has quantity 1, when I decrease it, then it is removed from the cart.
- Given that I want to delete a product, when I press "remove", then I am asked for confirmation first.
- Given that I have products in the cart, when I reload the page, then the cart keeps its content.
-
Frontend Sub-Tasks:
- Extend the Pinia cart store with actions to add, increment, decrement and remove products.
- Derive unit price, line subtotal, VAT and total with getters instead of storing them.
- Build the "Tu pedido" summary component with accessible quantity controls.
- Persist the cart in
localStorageand clear it after a successful order. - Write unit tests for the store and component tests for the summary.
-
How We Solved It: The cart store keeps only
{ product, quantity }for each line; prices, subtotals, discounts, VAT and total are computed getters, so they can never get out of sync with the product data. The VAT rate lives insrc/constants/tax.js(no magic numbers). TheCartSummarycomponent has no props or events — it reads and updates the store directly — so it can be reused in any view without changes. The state is persisted inlocalStorageafter every action, and a dedicatedclearCart()action empties both memory and storage after confirming an order.
Example 2: Frontend - Confirm the order
-
The User Story: "As a customer, I want to review a summary of my order and confirm it, So that the kitchen receives it and I know how to pay."
-
Acceptance Criteria:
- Given that my cart is empty, when I reach the confirmation step, then the "Confirm" button is disabled.
- Given that I am ordering on-site, when I have not selected a payment method, then the "Confirm" button is disabled.
- Given that I press "Confirm", when the request is in progress, then I see a "Confirmando..." state and cannot send the order twice.
- Given that the request fails, when the error is shown, then my cart is kept so I can try again.
- Given that the order is created, when the response arrives, then I see the payment status (e.g. "pendiente de cobro en caja") and I am redirected to "Mi pedido".
-
Frontend Sub-Tasks:
- Create the orders service (
POST /api/v1/orders). - Map the frontend state (channel, payment method) to the backend enums.
- Build the
OrderConfirmationcomponent with subtotal, discount, VAT and total. - Handle loading, error and success states with accessible feedback.
- Mark the applied exclusive offers as used after a successful order.
- Create the orders service (
-
How We Solved It:
OrderConfirmationgathers the data from the cart and checkout stores and sends a singlePOST /ordersrequest with the items, channel, payment method and chef note. Internal values are translated to the backend enums through mapping objects insrc/constants/(sala→ONSITE,cashier→CASH_ONSITE...). The created order is saved in thelastOrderstore for the ticket in "Mi pedido", thepaymentStatusreturned by the API is translated into a Spanish label shown in arole="status"message, and navigation waits a few seconds so the user can read it. Tests cover the disabled states, the payload sent, the error path and the delayed navigation (with fake timers).