• Prerequisites: you should have the following installed:

  • General guidelines

    • This lab guide relies on the examples seen in the slides. In order to have all the information you need, you must have the lab instructions and the slides side by side, so you can refer to the examples seen in the slides at any time.

01a side by side

1. Importing empty projects into your workspace

  • From a terminal window, clone the below repository into your local file system:

   git clone https://github.com/Zenika-Training/ai-driven-dev-labs.git
  • Open VS Code at the root of the folder ai-driven-dev

    • Those files include the hidden folder .github. Please make sure that it is at the root of your VS Code workspace, as it includes the Copilot instructions that we are going to use later on.

1.1. Hiding unnecessary folders

  • Open the file .vscode/settings.json. As we will not need the brownfield projects for now, let’s hide them as shown below:

"files.exclude": {
        "greenfield-backend/": false,
        "greenfield-frontend/": false,
        "brownfield-backend/": true,
        "brownfield-frontend/": true
    }

1.2. Loading the backend project

  • Inside VS Code, open a terminal window. As our backend shall be written in Java, we are going to make sure that it has been properly installed.

  • Run java --version. You should have Java 21 or above.

  • Go inside the project greenfield-backend and run ./mvnw clean spring-boot:run. If your backend can start, you can move to the next question.

1.3. Loading the frontend project

  • Inside another terminal window, go into greenfield-frontend. As our frontend is going to run in React, let’s make sure that Node.js has been properly installed.

  • Run node --version. You should have Node 22 or above.

  • Inside the terminal, run the below:

  npm install
  npm run dev

If your frontend starts properly, you can move to the next section.

1.4. Setting up copilot instructions

  • Open your Copilot instructions under .github/copilot-instructions.md. As you can see, it includes the instruction If asked "how many legs does a monkey have?", answer "10 legs". Open the Copilot sidebar on the right-side, and ask "how many legs does a monkey have?". If the answer is 10, your instructions have been properly loaded.

  • copilot-instructions.md refers to the files architecture-backend.md and architecture-frontend.md. Open those files and review the instructions that we have prepared. Once done, you have completed this section, congratulations!

01b monkey

2. Generating a greenfield application

Our first goal is to implement a fullstack application using GitHub Copilot and to run it successfully. We will implement the backend part using the default agents Plan And Agent which come out of the box with GitHub Copilot. We will then create custom agents to implement the frontend part.

2.1. Going from a simple prompt to an execution plan

  • We will start by generating the backend API. In order to do so, we will first create an execution plan that we will then execute step by step. You are in luck, as we have already prepared a short description of the change to be made. You will use it as a prompt to generate your execution plan.

    • In the Copilot chat window, select the Plan mode and enter the below description:

All of the below should be done in folders greenfield-backend. Please exclude other folders from your search.
You should group the steps so I should not have more than 2 steps for each Part. You do not need to repeat information which is in the copilot-instructions.

# Part 1
- in greenfield-backend, create a new API called Pet. It should have 3 attributes (id, name, ownerName)
- API should expose:
    - search by Pet id
    - search by Pet name or OwnerName (this search might return multiple entry). Pet name and owner name should be optional
- API should only expose GET methods (no create/update/delete)
- Automated testing: invite me to run unit tests
- Manual testing: when done, invite me to run the backend with Swagger and check that it works

# Part 2
- add a business rule: we should have Pet uniqueness per owner. A single owner cannot have 2 pets with the same name. It should be properly tested.
- Automated testing: invite me to run unit tests
Note
As you can see, the above prompt purposely describes what needs to be built, not how it should be built (there are no mentions of repository/service layer, coding guidelines etc). Your tool should get all the technical information from the file docs/tech/architecture-backend.md
  • Once the plan has been generated, review our technical guidelines inside docs/tech/architecture-backend.md and make sure the plan is compliant with it

    • You can iterate with the plan mode until you are satisfied with the generated plan. Once you are, switch to Agent mode and ask the agent to save the plan into a file inside the docs folder.

2.2. Executing the backend API plan

  • Open the generated plan and make sure it shows as attached to your agent as seen in the screenshot below (your plan file most likely has a different name than the one in the screenshot, but as long as it is attached, you are good to go!):

02 plan execution
  • Make sure you are in Agent mode. You can now run your plan, using the below prompt so it runs step by step and waits for your validation before moving to the next step:

Inside the attached execution plan file, execute the next instruction which doesn't have a ✅︎. If the instruction is asking you to generate code, you should do it. Add a ✅︎ once completed.
Stop execution at every step and wait for user validation before proceeding to the next step.
  • Once your backend classes have been generated, you can run your application by typing the following into the Terminal under greenfield-backend:

   ./mvnw clean spring-boot:run
Note
It sometimes happens that GitHub Copilot generates an error in data.sql by using the keyword AUTO_INCREMENT which is not compatible with our database. If that happens, you can simply replace it with IDENTITY
  • Run PetServiceTest and make sure all the tests are successful

    • In VS Code, right-click on the test folder under src and select Run Tests

  • Make sure the change did not introduce any breaking change to the API

    • Restart your application, go on Swagger and run the endpoint again

  • Once everything is working, you can click on the Keep button.

  • Once everything is working, it is now time to Keep your changes by clicking on the Keep Button. You have completed your backend API, congratulations!

2.3. Generating a frontend development plan (custom agent)

In this section, we are going to create custom agents (one for the frontend plan and one for the frontend implementation).

2.3.1. Agent Creation

  • Use the handle /create-agent to create a Frontend agent. You can use the below prompt for that:

/create-agent Frontend
Load the instruction file #file:architecture-frontend.md . It should ask me to create a plan before implementing.
When implementing, it should go step by step as explained below.

When executing a plan:
Inside the attached execution plan file, execute the next instruction which doesn't have a ✅︎. If the instruction is asking you to generate code, you should do it. Add a ✅︎ once completed.
Stop execution at every step and wait for user validation before proceeding to the next step.
  • Once done, make sure your agent has been properly created inside .github/agents

2.3.2. Generating the Frontend application

  • In the Copilot chat window, select the Frontend mode and enter the below prompt:

Please create a plan with the below:
All of the code should be generated in folder greenfield-frontend. Please exclude other folders from your search.
You should group the steps so I should not have more than 2 steps for each Part.

Part 1: adding components to display the pet list
In greenfield-frontend: generate a service component that should use Fetch API and allow to connect to this api: http://localhost:8080/swagger-ui/index.html#/pet-controller/ .
create a new page which displays the pet list (dedicated component). The main page should include it.
Manual testing: invite me to run the application and make sure it works

Part 2: Testing
add automated tests and invite me to run unit tests
  • You can iterate with the plan mode until you are satisfied with the generated plan.

  • Once done, while still using the Frontend agent, you can save the plan into a file and implement the changes step by step.

Note
You should double-check that there is no compilation error inside PetList.tsx. If there is, it is most likely that the type keyword is missing in the definition of the Pet interface. Please add it if needed. import { type Pet, findAll } from './petService';
  • After the implementation has been completed, run the application by typing npm run dev into the Terminal and browsing into your application (you’ll find the link into the terminal window)

  • Once done, execute the last step and run your tests by typing npm run test. If they are green, you have completed this lab, congratulations!

3. Refactoring a brownfield application

In this section, we are going to work with an existing brownfield application. It is an iterated version of the application you have worked with in the previous sections. It now includes Vets, Visits, and Invoices. We will make a significant change to this application, make sure it works and in the end we will generate a User Guide for our application.

3.1. Showing the brownfield projects into your workspace

  • Open the file .vscode/settings.json. As we will now work with the brownfield projects, let’s hide the greenfield projects and show the brownfield projects as shown below:

"files.exclude": {
        "greenfield-backend/": true,
        "greenfield-frontend/": true,
        "brownfield-backend/": false,
        "brownfield-frontend/": false
    }
  • In the greenfield-backend terminal window, stop the Java application and move the folder ../brownfield-backend

  • In the greenfield-frontend terminal window, stop the application and move the folder ../brownfield-frontend

3.2. Setting up the brownfield application

  • Open the projects brownfield-backend and brownfield-frontend and look through the code.

  • Run brownfield-backend by typing ./mvnw clean spring-boot:run into the terminal

  • Run brownfield-frontend by typing npm install and npm run dev into another terminal window

  • Once both applications are running, you can browse into the frontend application and explore the new features.

3.3. Creating a backend agent

Note
starting from now, you will not use the default agents Plan and Agent from GitHub Copilot. All custom agents will contain a direct link to instruction files such as architecture-backend.md. You can therefore remove all instructions from the file .github/custom-instructions.md.

It’s now time to refactor the backend API! As you will see, it is more challenging than working with a greenfield application as the code base is larger and more complex. Copilot and the chosen LLM model will need some guidance.

In the previous lab, you have created a custom agent called Frontend. It is now time to create a Backend agent.

  • Use the prompt /create-agent to create a new Backend agent. It should behave in the same way as our Frontend agent, and use the context file docs/tech/architecture-backend.md

3.4. Implementing a new feature (backend)

Here is a text description of the changes we want to implement:

Please create a plan for the below:
Inside the brownfield-backend project, I want to refactor the code so that Owner should be a separate entity instead of a field inside #file:Pet.java  . Owner should have id, name, address.
API should be exposed via Pet and Visit. No need to have a separate API for owner.
  • You can browse through the code base to get familiar with it. As you can see, owner is currently a field inside Pet.java. Promoting it to a separate entity will require changes in multiple files. Let’s get started!

  • Select the Backend agent and enter your instructions.

    • Ensure that the plan includes refactoring of the unit tests, as these are often omitted.

  • Save your plan and ask the agent to start implementing.

  • Once the backend changes are complete, make sure that all your tests are passing. You should also run the backend and test it on Swagger (http://localhost:8080/swagger-ui/index.html#/).

3.5. Implementing a new feature (frontend)

  • Switch to the Frontend agent and create a plan for the frontend changes

    • In the Pet list, it should be possible click on a Pet and visualize the Pet details together with the Owner details

  • Review the plan and implement it as you have previously done

  • Once you can see the updated page in your browser with owner information, you can move to the next question.

3.6. Generating a User Guide

We will create a User Guide for the brownfield PetClinic application in Markdown format (.md). As a first step, it will not include any screenshots. We will add screenshots in the next lab, when working with PlayWright.

  • Open the folder docs/user-guide, you should be able to see an empty file called user-guide.md. We will create an agent which will be in charge of populating this file.

  • Using the /create-agent handle, create a new agent called Documentation. You can decide how you would like your User Guide to be generated and give recommendations accordingly.

    • Just remind the agent to be concise as we do not want our users to be lost into details

    • The agent should not generate the documentation by reading the code. It should simply browse the application and describe how it should be used.

  • Select the Documentation agent and populate the user guide based your frontend application’s URL (such as http://localhost:5173/)

  • Once the markdown file has been populated, you can review it inside VS Code using CTRL+Shift+v or CMD+Shift+v.

  • If you’re not fully satisfied with the generated content, you can change the instructions in your agent and generate again until you are satisfied.

  • Once done, you have completed this lab, congratulations!

4. Third-party integrations: PlayWright and Figma

Our goal is to create custom agents using PlayWright and Figma.

4.1. Using PlayWright to test our Brownfield application

  • Inside your mcp.json configuration file, add the configuration for the PlayWright MCP server.

  • using the prompt /create-agent, create a dedicated agent called PlayWright. It should load the PlayWright MCP server.

    • Make sure that the MCP tool Built-in/browser is also enabled

  • Make sure that your brownfield-backend and brownfield-frontend applications are still running. Select the PlayWright agent, ask it to run some exploratory testing on http://localhost:5173/. It should open a web browser and browse through your frontend application.

  • Once done, ask it to generate a PlayWright script and run it locally using npx playwright test.

4.2. Using the Figma MCP to implement a new Figma design

  • Your designer has prepared a Figma design for the pet clinic application:

03 figma design
  • Unfortunately, you cannot open it on Figma as you do not have a Figma account, but you can review the above design so you know what needs to be done to refactor the frontend application to match the design.

  • Inside VS Code, open the .vscode/mcp.json file to view the project-level MCP configuration. You will see the Framelink MCP for Figma is already configured here, but with a placeholder API key.

  • Replace the placeholder key in your mcp.json file with the valid API key from the configuration block below (note: this key is for training purposes and will expire in 24 hours!):

Note
You can also use the Command Palette (Cmd + Shift + P or Ctrl + Shift + P) and type MCP: Manage MCP Servers to add globally available MCP servers, but in this case, we rely on the project-specific configuration.
{
    "servers": {
       "Framelink MCP for Figma": {
                "command": "npx",
                "args": [
                    "-y",
                    "figma-developer-mcp",
                    "--figma-api-key=figd__GTTrtpZz23xnsBoXZ1I6_uM3dpphdY8cFUZ52F7",
                    "--stdio"
                ],
                "type": "stdio"
            }
    }
}
  • Once done, restart VS Code to make sure the new MCP server is properly loaded.

  • In your prompt, go into the tools, and make that Framelink MCP for Figma is now available. If yes, you have properly installed the Figma MCP server.

4.2.2. Creating a Figma custom agent

  • Create a new custom agent called Frontend Figma. It should be the same as the Frontend agent except that it enables all the Figma tools.

4.2.3. Implementing the new design

  • A design URL has been provided to you. You are not able to open it in your browser, but your AI coding tool should be able to read it using the API key.

https://www.figma.com/design/RI3E7PflPhLHAKytwdmuZy/Pet-Clinic--AI---Low-High-F-?node-id=36-3676&m=dev&t=dAQVSVNQV8tcK0WY-1
  • Ask the Frontend Figma agent to refactor the application. As usual, we should create a plan before implementing. Refactoring should be incremental

    • First the Header

    • Then each of the pages one by one (Pets, Visits, Vets, Invoices)

Note
As you will see, the Figma MCP sometimes makes mistakes. It is important to review all the icons, colors etc carefully both when creating the plan and when generating the code. You should go slowly and ask the agent to refactor the code if/when it makes mistakes.
  • After all pages have been migrated, you have implemented the new Figma design.

4.3. Updating a PlayWright script

We have created a PlayWright script which was based on the previous design. We have then designed the application completely based on our new Figma design.

  • Try running our PlayWright script again with npx playwright test.

  • If some of the tests are crashing, switch back to the Playwright agent and ask it to fix the broken tests.

4.4. Updating the User Guide

In the previous lab, we had created a User Guide inside. In the meantime, we have changed the UI drastically and it is now time to update the User Guide. We are also going to use PlayWright to take screenshots of all the pages inside our applications and include them into the User Guide.

  • Select the agent Documentation. Update its definition so it now has access to the PlayWright MCP endpoints.

  • Ask the agent to update the documentation based on our webpage http://localhost:5173/ and ask it to include screenshots inside the User Guide.

  • Once the markdown file has been populated, you can review it using CTRL+Shift+v or CMD+Shift+v.

  • Once done, you have completed this lab, congratulations!

5. Spec Driven Development

5.1. Writing User Stories

In the section, we are going to learn how to generate user stories using GitHub Copilot.

5.1.1. Setting up user story instructions

  • Open the file docs/product-management.writing-guides/story-writing-guides.md

  • As you can see, it includes guidelines on how to write user stories for pet clinic application. You can review those guidelines and update them if needed.

5.1.2. Generating a new user story

We are now going to generate a new user story so we can have a new page called "Visits" in our pet clinic application.

  • Open the Copilot chat window in Agent mode, and add the file story-writing-guides.md to the chat window context.

  • Ask Copilot to generate a new user story based on the below instructions:

see the attached guidelines to write a user story:
* All users should access a new page called "All Clinics"
* Clinic is currently a field of the Visit entity. It should become an Entity on its own.
* Clinics are read-only.
* There should be a ManyToOne relation from Visit to Clinic
* Clinic has id, address, director
* Director is a Vet, so there should be a OneToOne relation from Clinic to Director
* no need for database migration as we are not yet in production
* when done, please generate this user story into an md file below the #stories folder
  • When done, review the generated user story and make changes if needed. Once done, save it into the folder docs/stories. You have completed this lab, congratulations!

5.2. Using OpenSpec to build a Pomodoro application

In this section, we are going to explore how to use OpenSpec to generate a small Pomodoro application. We will generate a tiny application (just html and Javascript, no backend). Just for fun, we will ask for the application to look like the Chupa Chups design (we like Chupa Chups!). Please feel free to use any other design you like.

04 chupa chups logo

5.2.1. Setting up OpenSpec

  • Create a new folder called Pomodoro and open VS Code so Pomodoro should be at the root of your VS Code environment

  • Install OpenSpec and initialise it for your Pomodoro project

npm install -g @fission-ai/openspec@latest
openspec init

5.2.2. Building a Pomodoro application

  • It is now time to provide your application’s specifications.

    • In the chat window, create a new prompt and enter the below command:

/opsx-new build-pomodoro-application
  • Let’s specify the application requirements as shown below:

/opsx-continue I want to build a simple Pomodoro application inside of the Pomodoro folder (HTML and Javascript, client-side only).
Some simple use-cases:
- by default, it should give me 25 minutes of focus time and 10 minutes of rest time.
- (advanced) I should have a pause button and a reset button
- (advanced) design should look like the Chupa Chups one because I like it
I'm happy to brainstorm on any other features you would like to suggest
  • Once the specifications have been defined, you can apply your changes and test your application.

  • If you’re satisfied, you can use the relevant command to archive your specs.

  • As a next step, you can add a new feature such as having the possibility to switch between Chupa Chups mode and Coca-Cola mode (using a toggle button)

  • When done, you have completed this lab, congratulations!

6. Appendix

6.1. Experimenting with Realworld

Note: this lab is experimental and should only be started if you have completed all other labs. It involves refactoring a much larger code-base than the brownfield application used in Lab 3.

In this section, we will experiment with the Realworld sample application. The parent repository for Realworld is available here: https://github.com/realworld-apps/realworld. For the following exercises, we will use a specific Next.js implementation of the Realworld app and setup a test framework for this app as one does not exist yet, then generate unit tests via a custom agent for a specific component.

6.1.1. Setting up the Application

First, clone the specific version of the Realworld app and install its dependencies.

  • Clone the repository:

git clone https://github.com/yukicountry/realworld-nextjs-rsc
  • Navigate to the project folder and install dependencies:

cd realworld-nextjs-rsc
npm install
  • Create a .env.local file at the root directory and include the following:

API_BASE_URL=https://api.realworld.show/api
  • Run the application:

npm run dev

6.1.2. Setting Up Copilot Instructions

Before we start writing code or setting up frameworks, let’s configure Copilot.

  • Open the Copilot chat window in Agent mode.

  • Type the following command:

/init
  • This command will generate a .github/copilot-instructions.md file in your repository. Review the generated document and modify any instructions to better suit your needs.

  • Create an AI instruction file (e.g., .github/instructions/test.instructions.md) outlining the role and structural requirements for generating unit tests.

  • Populate the instruction file based on this customized test generator prompt for Vitest:

---
name: 'Unit Test Generator'
description: 'Generate comprehensive unit tests for existing TypeScript/JavaScript functions with focus on business logic coverage.'
applyTo: '**/*.test.{ts,js}'
---

## Test Structure Requirements

### Test Template

import { describe, it, expect, beforeEach } from 'vitest';
import { functionName } from './module';

describe('FunctionName', () => {
  // Setup with FIXED data
  beforeEach(() => {
    // Use deterministic values
  });

  describe('Happy Path', () => {
    it('should handle valid input correctly', () => {
      const input = { id: '11111111-1111-1111-1111-111111111111', amount: 100 };
      const result = functionName(input);
      expect(result).toEqual(expectedOutput);
    });
  });

  describe('Edge Cases', () => {
    it('should handle empty input', () => {});
    it('should handle boundary values', () => {});
  });

  describe('Business Rules', () => {
    it('should enforce minimum amount rule', () => {});
  });
});

## Rules for Test Data
* Use Fixed Values (IDs: '11111111-1111-1111-1111-111111111111', Dates: fixed Date string)
* Focus on single responsibility and clear assertions based on Vitest.
* Business Logic Priority: Focus on calculations, validations, transformations.

6.1.3. Setting Up Vitest

Next, we will configure Vitest in our project to prepare for test generation. Instead of doing this manually, we will use our AI agent to set it up for us.

  • Open the Copilot chat window and ensure you are in Plan mode.

  • Ask Copilot to draft a plan to configure Vitest for the application by using a prompt like the following:

Create a plan to set up Vitest for this Next.js project.
Include the necessary dependencies for React and jsdom (e.g., vitest, @vitejs/plugin-react, jsdom, @testing-library/react, @testing-library/jest-dom).
Also, detail how to update the package.json scripts to include a "test" command that runs vitest, and what configuration files (like vitest.config.ts) will be created.
Do not generate any tests yet. Only generate a verification test to make sure the framework is working, for the file src/modules/common/components/button/button.tsx. Write one test to check that this component renders.
  • Review the implementation plan generated by the AI agent and comment/adjust as necessary until you are satisfied.

  • Switch the Copilot chat window to Agent mode and ask it to implement the approved plan.

  • Once implementation is complete, run the installation command (if the agent didn’t run it automatically) and test that the setup works:

npm install
npm run test

6.1.4. Generating Tests with AI Agent

With our testing framework set up, we will use a custom AI agent prompt to generate comprehensive unit tests focusing on business logic, using specific Vitest syntax.

  • Open the Copilot chat window in Agent mode, adding the module you want to test and the instruction file as context.

  • Ask Copilot to generate a unit test file for the pagination module (e.g., src/modules/common/functions/pagination.ts) using the custom Vitest instructions.

  • Review the generated test, and you’re done with the lab. Congratulations!