DynDaCo

Assessments for coaches, without a rebuild per questionnaire

Sector
Coaching and assessment
Period
2024–present
Role
Architect and sole developer
Stack
Ruby on Rails 8.1 · PostgreSQL · Hotwire · Pundit · Chart.js

Situation

A coaching practice ran its assessments on paper. The client filled in a form, the coach typed or tallied the answers, and then worked out the scores by hand against a scoring key — per dimension, per cluster, with weightings — before drawing the profile to talk through.

Two things are wrong with that, and the obvious one is the smaller one. Yes, it is slow: printing, posting or handing over forms, chasing the ones that come back half-finished, then an hour with a calculator per client.

The one that matters more is that hand-calculated scores are quietly unreliable. A transposed digit or a mis-applied weighting does not announce itself — it produces a plausible number, and a conversation about someone's development then proceeds from a wrong figure that nobody will ever check. Manual scoring is precisely the kind of repetitive arithmetic people are bad at and computers are perfect at.

There is a second, structural problem underneath. "Questionnaire" is not one thing: a multidimensional scale and a weighted-category instrument share almost nothing in how they are configured, presented or scored, while sharing everything in how they are assigned, completed and reported. Built the obvious way, each new instrument adds another branch to the shared code until nobody wants to touch it.

What I built

For the coach. Practices work as teams, with clients belonging to a team rather than an individual, so cover and handover work without transferring records. A coach assigns an instrument to a client and sees when it was opened, when it was finished, and what it produced. Billing sits alongside.

For the client. A link, and no account to create. The questionnaire renders from its definition, saves progress as it goes, and can be closed and resumed later — which matters, because instruments that take half an hour get abandoned otherwise.

For the results. Scoring runs automatically the moment an instrument is completed — every dimension, every cluster, every weighting applied the same way every time — and comes out as bar and radar charts the coach can walk through with the client. Nobody adds anything up, and the same answers always produce the same profile.

For the next instrument. Each questionnaire type is a self-contained handler that supplies its own defaults, validates its own configuration, builds its own form, scores its own answers and presents its own results, then registers itself. The core models know that types exist and nothing about what any of them do, so adding one is additive rather than invasive.

Two decisions make that hold. Configuration, answers and scores are stored as structured documents that serve as the single source of truth, with the rendered form generated from them rather than stored a second time — so there is only one representation that can be wrong. And every type must emit its scores in the same normalised cluster-and-dimension shape, which is what lets one set of charts render every instrument, present and future, with no type-specific branch in the reporting code.

Outcome

The paper is gone, and so is the calculator. An assessment that used to mean printing a form, waiting for it to come back and then an hour of manual arithmetic is now a link the client opens and a profile that is ready the moment they finish. The coach's time moved from administering the instrument to actually discussing the result — which is the part the client is paying for.

The reliability gain is the quieter one and probably the more valuable. A score is now a function of the answers, computed identically every time. Where a mis-added column used to be invisible, there is now nothing to add up.

And new instrument types ship without touching the core, so the practice can adopt a new questionnaire without a development project attached to it.

The general principle: find the one contract every variant must honour — here, the shape of a score — and enforce it at the boundary. Everything downstream of that contract then gets written once.

← All work