# Terminals to access data Terminals are dedicated applications or devices to interact with data. This is a very wide definition, a terminal can be an actual device like a point of sale, or a web application that shows the current stock for each location to a store manager. ## Command-line interface terminals This case study includes some simple terminals with a command-line interface (CLI) that are installed when installing the package: 1. `pos`: a point of sale. 2. `tasks`: a stocker terminal to assist operations at the store. 2. `stock`: a stock management terminal. Let's start a session as store manager with the last of the listed terminals with ```bash stock postgresql://postgres:postgres@host.docker.internal/retail 1 ``` The first argument to the `stock` command is the connection to the database, and the second is the ID of the location. The terminal greets us with the following message and a prompt: ``` Fetching data... ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ Retail twin stock management CLI ┃ ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ This is a simple terminal to manage stock. Enter a single-letter command followed by . The available commands are: • l: Lists all the current items stocked in any location • s: Enters search mode. Search an item by name • q: Store query mode. Queries the stock of an item by UPC in the current location • w: Warehouse query mode. Queries the stock of an item by UPC in all warehouses. Requires connection to the database • c: Cancel mode. Retires a batch giving a UPC. Requires connection to the database • b: Batch mode. Requests a given quantity from an item to the warehouse. Requires connection to the database • r: Refresh data from the stock database • h: Print this help message • x: Exit this terminal #> ``` This terminal, like any other terminal, provides a set of commands that interact with data in a a limited set of ways. The command `s` allows us to enter a keyword, and the terminal will return a set of related items: ``` #> s s> coffee Items ┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ upc ┃ name ┃ package ┃ ┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ 566807566244 │ Instant coffee │ 200g │ │ 212350582030 │ Coffee Beans │ 1lb bag │ │ 415996582616 │ Island Blend Coffee │ 1lb bag │ │ 167369617163 │ Ground Coffee │ 1 lb │ │ 982157811808 │ Coffee Beans │ 250g │ │ 86856869931 │ Ground coffee │ 12 oz bag │ │ 520101823089 │ French Roast Coffee │ 250 gram pack │ │ 240563892573 │ Fresh coffee beans │ 500g package │ │ 389837389865 │ Instant coffee │ 200g jar │ │ 940827785911 │ Pumpkin Spice Coffee │ 12 oz Bag │ │ 375920191429 │ Premium black coffee beans │ 500 grams │ │ 926526200297 │ Dark Roast Coffee │ 500 grams │ └──────────────┴────────────────────────────┴───────────────┘ ``` The query mode searches the stock of an item in particular in the current location: ``` #> q q> 566807566244 Item 566807566244 on location 1 ┏━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓ ┃ upc ┃ batch ┃ name ┃ package ┃ received ┃ best_until ┃ quantity ┃ ┡━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩ │ 566807566244 │ 20 │ Instant coffee │ 200g │ 2023-08-16 17:23:08.224154 │ 2023-09-15 17:23:08.224154 │ 193 │ └──────────────┴───────┴────────────────┴─────────┴────────────────────────────┴────────────────────────────┴──────────┘ ``` ## If it's smart it's vulnerable It's frequent to assume that CLI terminals are outdated, and more modern web-based user interfaces are the most common. But there many old-school terminals still around. Point of Sales terminals tend to be very basic as well, with displays only capable of showing a handful of characters, and a button for each command. Being this a digital twin, with complete freedom to implement anything we want, building a dumb terminal is important to introduce the following point: The most important constraint when designing enterprise data systems is information security, and the dumber the terminal, the more secure it is. PoS tend to be dumb because there's money inside. One key concept in information security is the *attack surface* of a system. A console with no graphical interface and a handful of commands connected to a database is inherently more secure than a web interface that needs a browser, a http connection, a web server, and a database. I can't recommend enough the book [If it's smart it's vulnerable](https://www.ifitssmartitsvulnerable.com/) by the veteran information security researcher Mikko Hypponen. Maybe that $200 cloud-connected PoS with a fancy screen from Alibaba is the door someone exploits to start a ransomware attack, or that simple web terminal that the cheapest bidder implemented is vulnerable to SQL injection. ![https://xkcd.com/327/](img/injection.png) [From XKCD](https://xkcd.com/327/) CLI Terminals also run everywhere, and require almost no support from the operative system. Here's the Windows command prompt running the `stock` terminal application. ![terminal.png](img/terminal.png) There's a 99% chance that the future Windows version released in 2033 is still able to run this application. That may not be valid for a web-based application developed with today's technologies. The most popular browser technology in corporate clients ten years ago was still Internet Explorer, and web applications had to implement support for it. ## API-based web applications Some terminals, like PoS, run on specific hardware with a dedicated display and user interface. CLI terminals' display is the operative system's console. Web applications' display is a browser, which is today almost as capable as an operative system. The entire Microsoft Office suite can now run on a browser. Web applications require the following components. * A database. Data has to be stored somewhere. * A web server that runs the business logic and interfaces data with presentation. * An application, or presentation logic, that runs on the browser. The code running on the database and the webserver is fequently called *backend* while the code running on the broser is frequently called *frontend*. It's obvious that implementing a terminal as a web application will require significantly more effort to develop, deploy and to secure that a CLI terminal. ![webterminal.png](img/webterminal.png) The previous image is a web application that implements an analogous set of functionalities as the previos CLI terminal. It can list the items that are available in each location, retire batches, list the available stock in terminals, search products... The implementation took roughly *ten times longer* than the CLI terminal, but it's clearly more powerful, feature-rich and easier to use. Web development is a field in constant change, and this makes technological choices harder, and more relevant. New frameworks and libraries are published every year, and the ecosystem is so fragmented that a software engineer will be fluent in a handful of those technologies in a landscape of hundreds of competing technologies. The design and implementation of effective user interfaces is as important as hard and time consuming. Don't assume users can be trained to use any user interface that *makes sense*. There should be constant usability tests to gather feedback from users to tune user experience. In the end, the web frontend is the only component of a very large ecosystem that the final user sees. Web application face the risk of not being successful because of a bad user experience. User interfaces are also important to prevent users to enter some wrong input and cause operational issues.