LabsFull applications

Lab 07Build a full web app from three models

A Library web application with tables, a bar chart and a chatbot, generated from a class diagram, a GUI model and an agent model, and running locally with Docker Compose.

Time
1 h 15 min
Level
Intermediate
Runs with
Browser, Docker
Do first
Lab 1

You'll learn to

  • Combine a class diagram, an agent diagram and a GUI model in one project
  • Generate a GUI from a class diagram and extend it with a chart and a chatbot widget
  • Generate the full web application and run it with Docker Compose
  • Fill the database through the generated REST API and see the data in the frontend

You'll need

  • A modern browser
  • Docker Desktop (or Docker Engine with the Compose plugin), running
  • About 5 GB of free disk space for the three images
  • A tool to unzip files

Files for this lab

A web application needs at least three things: the data it manages, the screens people use, and often an assistant that answers questions. In BESSER each of these is a separate model in the same project: a class diagram, a GUI model and an agent diagram. The Web Application generator reads all three and produces a FastAPI backend, a React frontend, one service per agent and a docker-compose.yml that starts everything.

In this lab you build a small Library application. You reuse two templates so the result is predictable, design the screens in the no-code GUI editor, generate the code, run it with Docker and fill it with data.

Create a Full Web Application project

  1. Open editor.besser-pearl.org and open File > New Project (on a first visit, click Start modelling on the Model it card).
  2. Name the project Library App, keep Low-code, and choose the modeling perspective Full Web Application. Click Create Project.
Create A Project form with the name Library App, the Low-code view and the Full Web Application perspective
The Full Web Application perspective shows exactly the three diagram types this lab needs
  1. Load the data model: File > Load Template, category Class Diagram, template Library, then Load Template. Click Quality Check; it reports “Diagram is valid”.

Add the Greeting Agent

  1. Click Agent in the sidebar.
  2. Open File > Load Template, choose the category Agent Diagram and the template Greeting Agent, then click Load Template.
  3. Click Quality Check. It reports “Diagram is valid”.
Greeting Agent state machine: initial, greeting, good and bad states connected by intents and Auto transitions
Each state has fixed text replies; intents decide which transition fires

Read the model before you continue. The agent waits in initial. When the user’s message matches greeting_intent (training sentences such as “Hi”, “Hello”, “Howdy”) it moves to greeting, which replies “Hi” and “How are you?”. The answer is classified as good_intent or bad_intent, the matching state replies, and an Auto transition returns to initial. No language model is involved, so the agent needs no API key.

Generate the GUI from the class diagram

  1. Click GUI in the sidebar. The page builder opens with an empty canvas. The REFERENCES bar shows that this GUI uses the class diagram Library.
Empty GUI editor with the device icons and the magic-wand button on the left of the toolbar
The magic wand next to the desktop, tablet and phone icons generates a GUI
  1. Click the magic-wand button, Auto-Generate GUI from Class Diagram.
  2. The dialog warns that it will clear the current GUI and lists what it creates. Click Generate GUI.
Auto-Generate GUI from Class Diagram dialog listing a navigation panel, a page per class and method buttons
Auto-generation replaces the whole GUI, so run it before you customise anything
  1. Open the Pages panel (the right-most icon in the panel toolbar) and click the Book page.
Generated Book page with a navigation sidebar, the Book List table, an Add Book button and a decrease_stock button
One page per class, each with a data table bound to that class and buttons for its methods

Add a bar chart and the chatbot widget

The table already exists. Add a chart of book prices and the Greeting Agent as a chat window on the Book page.

  1. Open the Open Blocks panel (the plus icon in the panel toolbar). Drag Bar Chart from the Basic group onto the Book page, below the decrease_stock button.
  2. Click the chart to select it. The Component settings panel opens. Set:
    • Chart Title: Book prices
    • Under Chart Series > Series 1: Data Source Book, Label Field title, Data Field price
Bar chart selected on the Book page with Chart Title Book prices and a series bound to Book, title and price
The preview shows sample bars; the generated app plots the real records
  1. Open Open Blocks again and drag BESSER Agent onto the Book page, above the Book List table.
  2. Click the widget. In Component settings, choose Greeting Agent in the Agent field and set Agent Title to Library assistant.
BESSER Agent widget titled Library assistant with Greeting Agent chosen in the Agent field
Choose the agent explicitly; the widget stores its name and the generated app connects to that agent

Generate the web application

  1. With the GUI editor open, choose Generate > Web Application. (From the class diagram, the same generator is under Generate > Web > Web Application.)
  2. The Web Application Generator dialog lists the diagrams it will use. Check that both required diagrams have a green tick, then click Generate.
Web Application Generator dialog with the Library class diagram and the GUI diagram ticked and one agent diagram available
Agent diagrams are optional and are included through the widgets that reference them
  1. The browser downloads web_app_output.zip. The zip has no top-level folder, so create a folder library_app/ and extract it there. You get:
library_app/
├── docker-compose.yml
├── BESSER_GENERATION.md
├── backend/          FastAPI app: main_api.py, routers/, sql_alchemy.py, pydantic_classes.py, Dockerfile
├── frontend/         React + TypeScript (Vite): src/pages/Book.tsx, Library.tsx, Author.tsx, Dockerfile
└── agents/
    └── greeting_agent/   Greeting_Agent.py, config.yaml, Dockerfile

Open frontend/src/pages/Book.tsx. Your GUI model is now code: you find <AgentComponent ... agent-name="Greeting Agent" agent-title="Library assistant" /> and a <ChartBlock ... chartType="bar-chart" title="Book prices" ...>.

Run the application with Docker Compose

docker-compose.yml defines three services: frontend on port 3000, backend on port 8000 with a SQLite database in the volume sqlite_data, and greeting_agent_agent with its WebSocket on port 8765 (and 5000).

  1. Make sure ports 3000, 8000, 8765 and 5000 are free, then start everything from library_app/:
docker compose up --build

The first build downloads Python, Node and PyTorch layers and takes several minutes (about 7 minutes on a fast connection; the agent image alone is about 3 GB). It is ready when the log shows these three lines:

backend-1               | INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
greeting_agent_agent-1  | ... Greeting_Agent's WebSocketPlatform starting at ws://0.0.0.0:8765
frontend-1              |  INFO  Accepting connections at http://localhost:3000

The agent also logs an error about the monitoring database (could not translate host name "YOUR-DB-HOST"). Monitoring is optional and the agent works without it.

  1. Open http://localhost:3000. The app opens on the Book page. The table and the chart are empty because the database is empty.
  2. Type Hello in the chat window and press Enter, then answer Fine.
Running app with the Library assistant chat: Hello, Hi, How are you?, Fine, I am glad to hear that!
The status turns to Connected when the frontend reaches the agent's WebSocket

Fill the database through Swagger and see it in the app

The backend is the same kind of FastAPI service you would get from Generate > Web > Full Backend, with interactive documentation at http://localhost:8000/docs.

  1. In Swagger, expand POST /library/, click Try it out, and execute:
{
  "name": "City Library",
  "address": "1 Main Street",
  "telephone": "+352 123 456",
  "web_page": "https://library.example.org"
}
  1. Create an author with POST /author/:
{
  "name": "Ada Writer",
  "birth": "1970-05-01"
}
  1. Create three books with POST /book/, changing title, price and genre each time. In the Library template a book can belong to several libraries, so library is a list here:
{
  "title": "Modeling 101",
  "pages": 240,
  "stock": 5,
  "price": 29.9,
  "release": "2024-03-15",
  "genre": "Technology",
  "library": [1],
  "authors": [1]
}

The other two books used in the screenshot are Patterns in Practice (42.5, Technology) and Night Train (12.0, Thriller). Remember that the OCL constraint requires more than 10 pages.

  1. Reload http://localhost:3000. The Book List shows the three books with their library and author, and the Book prices chart draws one bar per book.
Running app: Book List with three books and the Book prices bar chart
Table rows and chart bars come from GET requests to the backend
  1. Try the generated frontend as a user: open the Author page, click Add Author, fill in Name and Birth and submit. The form also offers the existing books as relationships. The pencil and bin icons in each row edit and delete records without Swagger.

When you are done, press Ctrl+C in the terminal and run docker compose down. Add -v (docker compose down -v) only if you also want to delete the database volume.

Exercise: a digital twin dashboard

Show a solution

Decide the multiplicities first: 1 on the PhysicalThing end and 0..* on the Sensor end means every sensor needs an existing physical thing when you create it. For the line chart, use timestamp as the label field and value as the data field.

Show a solution

Start from the Greeting Agent structure: one hub state that every answer state returns to with an Auto transition. Intent names must differ from state names, so use names like sensor_intent. Remember the host: 0.0.0.0 change in the new agent’s config.yaml before you run it.