Cultural heritage catalogue

A web application to catalogue artworks, archives, libraries and photographs with the records defined by the national standards. In 2026 I led its migration to newer technology.

What it is for and what it can do

For bodies and cooperatives cataloguing cultural heritage with standardised records. It belongs to the cataloguing offer ETT presents under its Scripta line, alongside digitisation and preservation.

  • Fills in records following ICCD standards, with controlled vocabularies and required fields.
  • Organises work in cataloguing campaigns, with assignment and validation of records.
  • Handles different roles: cataloguers, coordinators, archivists.
  • Exports delivered records.
  • Fits with the other cataloguing and metadata standards institutions use.

Context

Bodies and cooperatives that catalogue cultural heritage fill in standardised cards: hundreds of fields, controlled vocabularies, rules on required fields. The cards must be validated, assigned and delivered. The software belongs to the company where I work as a developer and has existed since 2006, written by many people.

The old system had a 2007 interface on a library no developer knew any more and that no longer worked on modern browsers, and about 57,000 lines of Python on Twisted with no written specification: the code was the only specification.

Before and after: the card

A card in the old 2007 interface
A card in read mode in the new interface, with the field tree
Before (2007)After (2026)
A card in read mode, in the old and the new interface. Example data; the old screenshot is cropped.

The migration

I followed the "strangler fig" strategy: instead of rewriting everything, I replaced the old system one piece at a time. First I wrote a wiki of the domain and tests that pin down the current behaviour; then I moved the backend to FastAPI and the interface to Vue 3, until in July 2026 Twisted and ExtJS left the running program. The twenty-year-old cataloguing rules were kept and covered with tests, not reinvented.

The system today (example data)

Some technical choices

  • Five layers (domain, repositories, services, schemas, API) with import rules enforced by a tool, and 14 written architecture decisions.
  • The content of a card is an immutable value; the JSON contract between backend and interface is generated from OpenAPI.
  • One database per client, with shared reference vocabularies.
  • A single importer for different formats (EAD, ArCo, digitised cards) that detects duplicates: 56,910 cards imported in about 45 minutes, 28 milliseconds per card.

What is mine and what is not

The program has more than 7,000 commits since 2006, almost all by other colleagues. Mine are two small fixes in March 2026 and, from June, the migration: about 1,600 commits covering plans, architecture decisions, tests, backend and interface. I did not write the software; I inherited a codebase and carried it forward.

I worked with an AI agent (Claude Code): it appears as co-author on about six commits out of ten since the migration. I set the plans and the decisions and checked the results; the agents wrote much of the code.

Limits and status

It is in use and under development, but it is not public and there is no demo. The declared version number and the repository tags are not aligned, and some functions described in the documents are studies only partly carried out. Two of the card layouts were left out of the first phase.

  • Stack

    Python · FastAPI · SQLAlchemy · PostgreSQL/PostGIS · Pydantic · Celery · Redis · Vue 3 · TypeScript · Pinia · OpenLayers · Docker · pytest · Playwright