William McVay: Full Stack Developer
To Do List
Legislator Lookup
I've rebuilt this little widget several times by now. Enough times from long enough ago that I don't even remember now where I initially reverse engineered the services that enable it to function. Probably the Delaware legislature's website since they also have a "find my legislator" widget on there.
The concept is simple enough. Put in your address (in Delaware) and it spits out your legislators. Under the hood it starts by geo-locating your address into a lat/lon which then gets fed into a separate service that looks up the districts you're a part of using different URL parameters on a single delaware.gov endpoint for your Election District, Representative District, Senate District, and County [Council] District.
I take it a step further and follow the URL provided for the state legislators to their legislative profiles and scrape the email address and photo to include in the output.
It's not overly complicated, but in the course of writing code for local political parties it's something that has often been useful or at least cool looking. I've done it so many times that this particular rewrite, with the benefit of VS Code's LLM-driven auto completion, was done in a couple of hours and uses Next.js, Tailwind, and all the other newfangled fanciness.
IBM 3270 - Why?
One of the more obscure technological skills listed on my resume is "IBM 3270".
Even among other coders that isn't something most people are likely to be familiar with. So what is it and why do I know anything about it?
I have recently taken a job with the State of Delaware as a part-time, casual employee in the Kent County Office of Conflicts Counsel. OCC is an office within the Office of Defense Services, colloquially known as the public defender though technically according to the org chart both the Public Defenders' Office and the Office of Conflicts Counsel are equal under the broader umbrella of the Office of Defense Service. My boss would want me to point that out.
I was technically hired as a legal administrative assistant, but between a pre-existing personal relationship with the two other people who work in my office, including the Managing Attorney, and my technical skills I was upfront that I would like to dedicate at least part of my time to justifying my position as a technical role. After so long out of the work force and even now technically out of the tech industry, I wanted to get a technical position on my resume even if most of my day is absorbed with legal administration.
The technical aspect of my job has really taken off after two months working there though. It took 2-3 weeks just to get the required training to access all of the technical systems and then another couple of weeks wrapping my head around the various workflows in the office as we assign indigent clients referred by the public defenders' office to contract criminal defense attorneys in the area due to conflicts the public defenders have which preclude them from ethically providing representation in criminal matters.
I have also confronted numerous challenges within the environment seeing as several of the systems we rely on are hidden behind the State's VPN and secured with a web proxy and other security policies which prevent me from having my way with my work machine. There are some things I can't install, some systems I can't access, and some things I can't do even with the things I can reach.
I have now though, fairly quickly all things considered, gotten much of the necessary infrastructure in place and through obsessive, hyper-focused R & D efforts, found ways to access most of what needs accessing using custom written Node.JS scripts. The most critical and most unusual system has to be the DelJIS system used by law enforcement and the courts to keep track of criminal cases from investigation and arrest through disposition by the three criminal courts in the state.
This system relies on an IBM3270 mainframe and an emulator terminal.
The terminal pre-installed on my machine and in use on the various computers throughout the courthouse for public access is the QWS3270S application from Jolly Giant Software. It's functional enough and it turns out there's even a scripting language approximately no one seems to be aware of, much less familiar with, that enables some basic automation all by itself. Combined with Node using the child_process and fs libraries, it becomes possible to dynamically generate QWS3270 scripts and launch them to aid in the completion of SOME tasks.
However, this scripting language and the application that hosts it does have real limitations. There are no scripting commands to read information from the terminal screen and re-input it into the search fields. The only mechanism for returning data from the terminal to a Turing Complete programming environment able to utilize it is to save entire portions of the screen to disk, use a more robust programming language program outside the emulator to notice updates to a targeted file, and then restart a brand new terminal session with a freshly written dynamic script file and begin all over again from the login steps to utilize the data already so painstakingly pulled from the previous set of interactions. All the while the terminal screen from the QWS application flashes with constant epileptic updates as the script drives it.
Enter the x3270 emulator application. Calling it an "application" in comparison to QWS seems generous. It's a command line interface application (CLI) that in alternative versions will actually mimic much of what QWS will do in the more limited UI of the command line, alternately showing the terminal screen and allowing direct input of scripting commands similar to those supported by QWS, and a headless mode that even requires a command be sent in order to dump out the contents of the "screen", such as it is, to the process's standard out stream.
This last version has become my bread and butter.
No longer am I bound by the constraints of the QWS application and no longer do my own users (so far consisting of me, myself, and I until I get to the point I can make this all user friendly enough for my non-technical coworkers to benefit from it) need to suffer through the flashing updates of a primitive looking terminal screen as a foreign scripting language rushes through the automated performance of the same keystrokes and button presses a human user would need to perform in order to accomplish the same task.
I can finally drive the whole thing directly from a Node application, which will eventually (in theory) have a user-friendly React application on top of it, to invisibly submit commands to the IBM3270 server and pull responses directly from the stdout stream without dumping those responses to the screen first. Better yet, after pulling those responses from the output stream, the necessary data can be stripped out and shoved right back in to create a truly functional automated system that can look up our new cases, identify other cases involving the same defendant, download the affidavits of probable cause from the arresting law enforcement officers, and then find all the individuals involved in the cases as well as any other pending cases that have yet to be declared conflicts and ensure one of our attorneys is free of any conflicting obligations with anyone else in the case.
I'll even be able to populate the PDF conflict sheets with the assigned attorneys and draft an email to their firms informing them and the courts of the pending assignment.
I can't send the emails though. There's an Office 365 policy blocking the Power Automate application from sending emails outside the delaware.gov domain. I also can't get the necessary credentials to access the exchange email server directly from my code. I can dump the documents on OneDrive though and automatically create an email DRAFT I only need to send, so I've got a workaround until it's all mature enough that I can go up the chain of command and maybe even get permission to do all this stuff the right way.
I'm having fun though and if it works it will save Zoƫ and I a bunch of time and effort.
kOS: Kerbal Operating System
Another game I enjoy playing is "Kerbal Space Program". Similar to Space Engineers, the purpose of the game is to design, build, and fly space ships. The key difference is that KSP relies on realistic physics and requires a basic grasp of orbital mechanics to succeed and has no vanilla mechanism for automating the spaceships using code. There is, however, a mod that enables this functionality called "kOS" or "Kerbal Operating System". The mod introduces a few new parts that allow players to write scripts in a unique kOS language to control various aspects of the attached ship.
One of the existing features in the KSP campaign mode is the requirement to unlock new parts by performing science experiments in different settings. Limited science points are available around the starting space center with more points available from advanced experiments in orbit of or on the surface of different planets and moons. The tedious grind comes when you fly a craft jam packed with experiments and experiment storage parts to a distant setting and then need to manage the interactions with all of them to exhaustively collect the science data and store it for transmission or return to the home planet.
While the kOS mod allows player to automate many of the functions of their space craft, when I first installed it there was no mechanism for "collecting" the science data from experiments into the storage containers. I found this limiting so I cloned the source repository for the mod, spent some time learning the code base, and created a pull request to implement this functionality. I was satisfied to learn that the pull request was eventually merged into the main codebase of the mod.
"JRRagon" Chess
First off, "JRR" are my daughter's initials and her nickname has been "the Dragon" since before she had a name, hence "JRRagon", and I built this after she first started getting into Chess.
The video is a quick demo of some of the functionality that had been completed as of the time of recording the video. The first game is played automatically using the rudimentary "AI" that just chose legal moves at random. "PERFT" is not quite an acronym used in Chess AI programming to mean "performance test" and "PERFT(1)" is looking ahead by one move, so when the window shows "PERFT(1)", it's showing all the legal moves the active player could make from that board position. Since the AI is still in (very) early development here, the green highlight is the "best" move, which is evaluated based on nothing and is actually selected entirely at random. The game is pretty long (151 moves) because it's hard for either side to gain a real advantage when it has no strategy at all.
The second game allows White to win by "Fool's Mate". Black can win by "Fool's Mate" in only two moves while it takes White three, but for no particular reason I played the slightly longer game.
Several other features are hinted at without being demoed on the pause screen, including loading and saving; setting a custom board position using "FEN", a condensed means of storing a game state including board positions, active player, castling rights, etc; and setting up a network game. This video was made prior to the establishment of the Node "Lobby" server, so network games at this point were constrained to clients running on directly accessible hosts.