i
Backend DDH ()


Backend

Kastalia's backend is a Perl application built on the Dancer2 web framework, storing its graph in PostgreSQL. This section describes the two layers that matter most: the SQL core (the actual table/enum design behind knots and bounds) and the PERL Core (the routes and helper functions that read and write it).

SQL core

Two tables carry almost the entire system: knots(knot_id, knot_name, knot_content, attributes hstore) and bounds(bound_id, sub, predicate, obj, ord, bound_creator).

attributes is a Postgres hstore column -- an open-ended set of key/value string pairs -- rather than a fixed set of typed columns. This is what lets a knot carry wildly different metadata depending on what it's being used for: a presentation knot might have ogg_url and presentation_timeline; an image knot an img_url; a person knot an age or voice. No schema migration is needed to introduce a new attribute -- any route can simply start writing a new key.

predicate, by contrast, is a proper Postgres ENUM type, not a free string -- a closed, explicit list of the relation kinds the graph currently understands (is_parent, contains, is_member, is_uttered_as, illustrates, translates, echoes, is_linked, and a handful of others). Extending the vocabulary means explicitly adding a new value to that enum (ALTER TYPE predicate ADD VALUE ...) -- a small deliberate act, not an accident of someone typing a slightly different string.

PERL Core

The application's Perl code lives under lib/Kastalia/. Main.pm defines almost every HTTP route -- what URL does what. Core.pm, TT.pm, SelectorQueries.pm and API.pm have no package statement of their own: they are require'd straight into Main.pm's namespace, so every helper function they define (addKnot, addBound, addAttribute, the various graph-query helpers used by templates, and so on) is directly callable, unqualified, from anywhere in that merged namespace -- effectively one large shared toolbox rather than several separate modules. User.pm is the one exception that keeps its own package Kastalia::User, for the LDAP-backed account/login logic, while still sharing the same Dancer2 app context.

Dancer2 itself handles routing, sessions (backed by Memcached) and the Template::Toolkit rendering described in the Frontend section.