The operational problem.

Placement work is not one dashboard. A school has to coordinate cohorts, students, host organisations, tutors, dates, hours, check-ins and signed evidence. Different roles need different views of the same record, and corrections must not erase what happened before.

The earlier academic implementation could not be reused as a product codebase. I rebuilt VECTOR from first principles, using only the placement domain as a reference. No legacy code, personal records, names or assets entered the new repository.

What a school-owned system must guarantee.

The architecture starts with four practical constraints:

  1. Each installation belongs to one school, which owns its database, branding, backups and deployment.
  2. Permissions and tutor scope must be enforced by the server before records are selected, counted or exported.
  3. Each placement keeps the programme version that defined its hours, check-ins and evidence; corrections preserve the original operational record.
  4. Imports, exports, retention and recovery must be bounded, reviewable and safe to repeat after a failure.

Choose the ownership boundary first.

Keeping more state in the browser would still leave the difficult questions unanswered. It could hide role checks in the interface, load an entire school into memory and treat a changed field as if no previous value had existed.

VECTOR uses one school per installation instead of building a shared multi-tenant service. That gives each school a clear operational boundary and makes backup, retention and white-label configuration easier to reason about. It also means the project ships software, not a managed cloud platform.

A compact server with explicit boundaries.

The browser workspace talks to an Express API that owns authentication, role checks, programme versions and workflow transitions. SQLite stores one school’s records in WAL mode. Opaque AES-GCM cursors bind coverage and attention views to school, role, filters and stable positions without exposing their contents.

A compact server with explicit boundaries. The server decides what an operator may see and change; the browser renders that decision.SYSTEM VIEW / VECTORBROWSERWORKSPACEEXPRESSPOLICY LAYERPROGRAMMEVERSIONSSQLITE WALAUDIT +RECOVERYVERSIONED DELIVERY PATH
The server decides what an operator may see and change; the browser renders that decision.

Why the deployment stays compact and school-owned.

The stack follows the chosen ownership boundary: one institution, one installation and one recoverable record.

T01 The choice

Each installation serves one school.

Why
Database ownership, branding, retention and backups align with one operational institution, making the scope of every record and administrative action explicit.
What I ruled out
A multi-tenant SaaS could centralize upgrades, but it would require tenant isolation, shared service operations, account recovery and governance that are outside this product’s contract.
What it cost
Every school operates its own deployment and cannot rely on a managed fleet, cross-school reporting or built-in high availability.
T02 The choice

Express and Node.js own the authorization boundary.

Why
The API applies role and tutor scope before selecting, counting, changing or exporting records, and it owns the workflow transitions that preserve evidence history.
What I ruled out
A browser-only application could render forms, but client-side checks cannot protect a shared school record from another operator or a modified request.
What it cost
The institution must run and update a server, and API, session and migration contracts need ongoing compatibility work.
T03 The choice

SQLite runs in WAL mode behind explicit migrations.

Why
A single-school installation gains transactions, strict relational records and a database that the supplied backup and inspection tools can snapshot as one owned artifact.
What I ruled out
PostgreSQL or a cloud database would offer a larger concurrency and availability envelope, but it would add another administered service to a deliberately compact deployment.
What it cost
Write concurrency and scaling remain single-node concerns, and reliable use depends on maintenance windows, tested backups and guarded restore procedures.
T04 The choice

Docker and repository-owned backup tooling define the deployment path.

Why
A school can run the same packaged service, inspect a snapshot without starting the application and restore through an explicit maintenance workflow while retaining custody of its data.
What I ruled out
A managed platform could absorb infrastructure work, but it would move runtime, storage and recovery decisions into a provider-specific service.
What it cost
The operator remains responsible for patches, secrets, storage, monitoring and recovery drills; containers alone do not provide compliance or high availability.

Decisions that make daily use safer.

The product favours visible rules over convenient hidden state.

D01

Version the rules, not only the placement

A published programme version is immutable. New rules apply to new assignments, while an existing placement keeps the target hours, check-in minimum and evidence set it started with.

The trade-offCorrections require a new programme version and untouched placements may need explicit reassignment. In return, completion never changes retroactively because a coordinator edited a policy.

D02

Show planning gaps before they become exceptions

Coverage is calculated for a cohort and placement period, distinguishing a valid assignment, no assignment and overlapping assignments. An uncovered row can start a prefilled placement without losing the active planning context.

The trade-offCoverage is a deliberately bounded operational view, not a general reporting engine. Its narrow scope keeps the result actionable and role-correct.

D03

Derive attention from records already owned

The attention inbox derives due work from evidence, hours, dates and tutor assignments rather than maintaining a second task list. Server-side role scope is applied before counting or paging results.

The trade-offThe queue cannot hold arbitrary reminders. It stays consistent with the placement record and avoids a parallel source of truth.

Self-hosting and recovery.

Schools can set their own name, colours, logo and support details with revision checks that protect concurrent edits. The pinned Node 24 Alpine image runs as a non-root user with root-owned application code, no package-manager toolchain and support for a read-only root filesystem. Health and doctor commands fail before normal use when configuration, schema or storage ownership is unsafe.

Backup tooling creates a size-bounded private SQLite snapshot, inspects it without starting the application and restores it through a guarded maintenance path that detects path replacement and source changes. Release automation scans the container and source for vulnerabilities and secrets, publishes an SBOM, builds the source package twice and verifies the extracted acceptance path before publication.

What VECTOR supports today.

A school can publish programme rules, inspect cohort coverage, create placements from planning gaps and work through a role-scoped attention queue. The same record still supports hours, check-ins, evidence history, scoped audit, atomic import, filtered export and governed retention.

VECTOR is self-hosted open-source software. It is not a managed SaaS, and it does not claim compliance certification, high-availability deployment or SSO. Those remain deployment and product work for an institution that needs them.

Evidence ledger.

The signed v3.4.0 release ties its product claims to concrete controls:

Programme policy
Coordinators publish immutable versions with target hours, minimum check-ins and evidence requirements. Existing placements keep the version they were assigned.
Bounded operations
Indexed, stable student and host pagination, batched import validation and database-backed capacity limits keep lists, placement history, sessions and the administrator directory within explicit operational envelopes.
Storage and recovery
Startup, doctor, backup, inspection, compaction and restore reject unsafe SQLite aliases and schema drift, validate WAL companion files, and keep integrity checks and snapshots on the guarded connection they opened.
Request and session boundary
Exact production origins, identity-blind login failures, duplicate-cookie rejection, timing-safe CSRF checks and a ten-session cap are enforced before a role-scoped workspace can expose school records.
Verification and release
Node 22 and 24 gates, Chromium and WebKit acceptance, native coverage floors, scale and CRUD rehearsals, Trivy scanning and two byte-identical package builds protect the release. The verified signed tag resolves to commit fb802e5, and the immutable GitHub release publishes eight digest-bound assets including its CycloneDX SBOM.

Verified release v3.4.0 Verified on

What this case can prove

This case study describes the immutable v3.4.0 release and its self-hosting controls at commit fb802e5. GitHub Pages is a product tour; the operational application runs from the server package. No real school records, institutional integrations or placement outcomes are represented, and the release does not claim managed availability or compliance certification.

Visit the working project