Self-initiated

Switchboard

One shared queue for everything a small team is asked to do.

Web app · Internal toolsIn progressOpen the device-local demoAll work

The idea

A shared request can be easy to see and still be nobody's responsibility. When work arrives through separate conversations, its owner, current state and history can become detached from the original request. Switchboard is a self-initiated concept for a web app that keeps those pieces in a shared queue.

The intended unit is a request with a description, an accountable role and an explicit state. The aim is to make the next action readable without turning routine coordination into an elaborate project-management exercise. A queue is useful when it makes responsibility obvious; it becomes counterproductive when it demands a ceremony for every small question.

That balance drives the engineering problem. The interface needs to show a simple current state, while the underlying system must retain enough evidence to explain how it got there. This page explores that boundary. It is not a connected workspace or a record of client work, and the sample interaction does not claim to assign, notify or audit anything.

State path

Switchboard request state machineA request moves from received to assigned, in progress, and closed on a gold path. A teal blocked state can return to in progress. A parallel ink audit rail records every state event. Received Assigned In progress Blockedneeds inputresume Closed received assigned started blocked closed Audit trail Switchboard request state machineA vertical version of the request state machine. The teal blocked branch returns to in progress, and an audit rail records each event below. Received Assigned In progress Closed Blockedneeds inputresume Audit trail state event recorded history remains readable
  1. A request enters the shared queue as received.
  2. It becomes assigned when an accountable role takes responsibility.
  3. Assigned work moves into progress and can proceed to closed.
  4. If an external dependency prevents action, the teal blocked branch records that state and returns to in progress when work can resume.
  5. An ink audit rail records each state event separately from the current state.

The rail is deliberately parallel rather than hidden behind a history drawer. Current state answers what should happen next; the event record answers why a reader should trust that state. Combining both in a mutable status field makes the interface compact, but turns explanation into memory and makes a disputed transition difficult to reconstruct.

Decisions we made

  • Make transitions explicit.

    The proposed state machine separates received, assigned, active, blocked and closed work. Each transition would have a permitted actor and a recorded reason where needed. A free-text status field was rejected because it lets every reader invent a different lifecycle; the accepted trade-off is that the system must define valid transitions before it can feel effortless.

  • Enforce permissions at the server.

    The interface would show actions appropriate to a role, while the API would independently check access on every request. Hiding a button is not authorisation. This is less convenient than trusting the browser, but shared work needs the rule to hold when someone uses a different client, repeats a request or arrives through an integration.

  • Record events alongside current state.

    A transactional update would store both the request change and its audit event. An append-only history would explain how the current state was reached. The cost is retention and access-policy work rather than simply overwriting a row, accepted because an audit trail that can be silently revised is not a useful account of shared work.

  • Treat live updates as a convenience.

    The planned interface would reconcile against server state after a reconnect. An update notification should not be the only source of truth. A purely live client was rejected because a missed event can leave a convincing but stale screen; version checks and a readable recovery path matter more than a momentary animation.

What it does

Filter the illustrative queue by state using the controls below. The selected filter has a visible pressed state, and a short message announces the change. Each request shows a role instead of a person's identity. No personal or customer data appears in the example.

Filtering is the entire working interaction here. It does not assign work, enforce permissions or create audit records. The sample requests live in the page and reset on refresh. This small study tests whether a queue can stay readable before the harder shared-state behaviour is implemented.

Shared requestsLocal study

A clear next action.

  • Review access requestOperations · Incoming
  • Update handover notesProduct · Active
  • Clarify export formatEngineering · Incoming

Showing all requests.

Illustrative requests · No connected workspace

Stack

Proposed: TypeScript for the web interface and API, PostgreSQL for requests and audit events, and server-sent events for update notifications. A transactional database is a useful starting point for keeping state changes and history together. Authentication, workspace isolation and reconnection behaviour remain design and implementation work.

The technology choice follows the state boundary rather than a preference for a dashboard stack. The data model needs an authoritative transition, a durable event and a way to reject a stale change together. That contract deserves tests before adding presence indicators, activity feeds or any feature that makes a queue appear more complete than its rules.

Status

In progress. Switchboard is self-initiated concept work, not a client commission or a released shared application. A device-local demo now exists: it stores a queue in IndexedDB, demonstrates role-specific permissions through a person switcher, enforces the state path, keeps an append-only audit trail, and exports the queue with its full history.

There is no sharing between devices, no server, no accounts, no authentication, no presence, no live updates, and no sync. The demo does not claim otherwise: every request and audit event remains on the device running it.