Architecture overview
=====================
-Books
------
+Catalogue of books
+------------------
-Books are kept in the :py:class:`catalogue.models.Book` model. Dublin Core
-metadata, read by :py:mod:`librarian.dcparser.BookInfo`, are put in the
-`extra_info` JSON field.
+Books are kept in the :py:class:`catalogue.models.Book` model.
-Authors, kinds, epochs, genres are kept in :py:class:`catalogue.models.Tag`
-model with `category` field set to appriopriate value.
+Books have fragments, annotated with themes. Those are kept in the
+:py:class:`catalogue.models.Fragment` model.
-:py:class:`catalogue.models.Tag` also contains :ref:`user-shelves`
-and :ref:`parent-relations`.
+Both ``Books`` and ``Fragments`` can have ``Tags``, which are
+:py:class:`catalogue.models.Tag` objects.
+What are ``Tags`` used for?
+---------------------------
-User shelves
-------------
+Each ``Tag`` objects has a ``category`` field specyfying its meaning.
+The categories are enumerated in :py:const:`catalogue.models.tag.TAG_CATEGORIES`.
-User shelves (or tags on user's shelf) are just :py:class:`catalogue.models.Tag`
-objects with ``category='set'`` and ``user`` set to the owner. Shelves' slugs
-are generated automatically using :py:fun:`catalogue.utils.get_random_hash`.
+Tags are used for:
+* Keeping browsable metadata. Each ``Book`` can have any number of tags
+ of categories: ``author``, ``epoch``, ``kind``, ``genre``.
+ Each ``Fragment`` of a book has all of those,
+ and also a number of ``theme`` tags.
+* User shelves. A User can put a ``Book`` on a shelf and add some labels
+ by adding a number of ``set`` tags to it. A book put on a shelf without
+ any labels has a Tag with an empty name.
-Parent relations
-----------------
-The source of parent relations is the
-:py:class:`librarian.dcparser.BookInfo.parts` metadata.
+.. _ancestor-descendant-relations:
-Parent relations are kept primarily in the :py:attribute:`catalogue.models.Book.parent`
-and :py:attribute:`catalogue.models.Book.parent_number` fields.
+Relations between ``Books``, ``Fragments`` and other ``Books``
+--------------------------------------------------------------
-They're also cached as :py:class:`Tag <catalogue.models.Tag>` relations.
-Each book has its tag (with :py:attribute:`slug <catalogue.models.Book.slug>`
-starting with ``l-``). All of book's descendants (NOT the book
-itself) have its tag attached.
+Obviously, every ``Fragment`` comes from a particular ``Book``. This
+relation is expressed with the Fragment's ``book`` field.
-Arguably, this scheme has some potential for inconsistency.
+The source of parent-child relations between ``Books`` is
+the ``dc:relation.hasPart`` metadata field, exposed by
+:py:class:`librarian.dcparser.BookInfo` as ``parts``. This relation
+and the order of children of one parent is expressed with the child
+book's ``parent`` and ``parent_number`` fields.
+
+Additionally, every ``Book`` has a many-to-many relationship `ancestor`,
+onnecting it to all its ancestors, with reverse relationship called
+`descendant`. This relationship is rebuilt after a `Book` is published.