pastoralist/pastoralist.adl.xml

258 lines
11 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- DOCTYPE application PUBLIC "-//JOURNEYMAN//DTD ADL 1.4.7//EN"
"http://www.journeyman.cc/adl/stable/adl/schemas/adl-1.4.7.dtd" -->
<application xmlns="http://bowyer.journeyman.cc/adl/1.4.7/"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:adl="http://bowyer.journeyman.cc/adl/1.4.7/"
name="pastoralist"
version="0.0.1">
<documentation>A web-app intended to be used by pastoralists in managing
pastures, grazing, and animals.
TODO: If this is intended to share data between systems -- as it must, if
for example, it is tracking the movement of animals between holdings --
then
1. Keys must include a unique identifier of the instance on which they
were created, as serial identifiers will not be unique across machines;
2. It had better implement [ActivityPub](https://www.w3.org/TR/activitypub/).
</documentation>
<entity name="holding" magnitude="7" volatility="1">
<documentation>All holdings used to the system</documentation>
<key>
<documentation>Although in the UK and, probably, in many other
countries, holdings have a unique, government issued, holding
number which could rationally be used as a key, internationally
we cannot rely on this.
</documentation>
<property required="true" type="integer" name="id"
column="id" immutable="true" distinct="system">
<generator action="native"/>
</property>
</key>
<property size="64" type="string" name="holding-identifier" distinct="all">
<prompt prompt="Holding Number" locale="en_GB.UTF-8" immutable="true"/>
</property>
<property size="128" type="string" name="name" distinct="user"/>
<property type="list" name="pastures" entity="pasture"/>
<property type="list" name="animals" entity="animal"/>
<property type="link" name="user-accounts" entity="user-account">
<documentation>A user is a person authorised to see data on a holding.
Some users (e.g. vets, farm secretaries) may be authorised to see data
on many holdings.</documentation>
</property>
<property name="is-active" type="boolean" default="true">
<documentation>Records are not normally deleted from this system because
of historical data integrity; we may want to trace the history of an
animal across holdings even after a holding has ceased to be active
in the system.</documentation>
</property>
</entity>
<entity name="pasture" magnitude="8" volatility="2">
<documentation>A pasture within a holding. TODO: how should common pastures,
or pastures otherwise shared between holdings, be handled?</documentation>
<key>
<property required="true" type="integer" name="id"
column="id" immutable="true" distinct="system">
<generator action="native"/>
</property>
</key>
<property size="128" type="string" name="name" distinct="user"/>
<property type="real" name="area" distinct="user">
<prompt prompt="Area in Ha" locale="en_GB.UTF-8"/>
</property>
<property name="holding" type="entity" entity="holding" required="true"/>
<!-- property name="geometry" type="entity" entity="polygon" required="true">
<documentation>
Polygon is a first-class datatype in PostGIS, but ADL does not yet
support this. Solutions:
1. hack ADL to support native polygons;
2. implement our own polygon datatype;
3. work-around in override code.
Generally, when pasture boundaries are changed, a pasture record
should not be edited; rather it should be marked inactive, and new
pasture record(s) created.
</documentation>
</property -->
<property name="subdivision-of" type="entity" entity="pasture"/>
<property name="is-active" type="boolean" default="true">
<documentation>Records are not normally deleted from this system because
of historical data integrity; we may want to trace the history of a
pasture even after pasture boundaries have been changed.
Indeed, if we treat subdivisions as pastures (which would be quite sensible),
active pastures in the system will change quite frequently, especially if
strip-grazing is used.
</documentation>
</property>
<property name="history" type="link" entity="event"/>
</entity>
<entity name="animal" magnitude="9" volatility="5">
<documentation>An animal on a holding (or which has been on a holding; the
historical record is not wiped when an animal dies, is killed, or is sold)
</documentation>
<key>
<documentation>Although in the UK and, probably, in many other
countries, animals have a unique, government registered, identifying
number which could rationally be used as a key, internationally
we cannot rely on this.
</documentation>
<property required="true" type="integer" name="id"
column="id" immutable="true" distinct="system">
<generator action="native"/>
</property>
</key>
<property name="holding" type="entity" entity="holding">
<documentation>The holding the animal is currently on, if any. Not 'required',
since the animal may be dead, or simply moved off to a holding which is
not part of the system.</documentation>
</property>
<property name="dam" type="entity" entity="animal"/>
<property name="sire" type="entity" entity="animal"/>
<property name="born" type="date" immutable="true" required="true"/>
<property name="animal-identifier" type="string" size="64" distinct="user" required="true">
<prompt prompt="Ear-tag Number" locale="en_GB.UTF-8"/>
</property>
<property name="name" type="string" size="64" distinct="user"/>
<property name="gender" type="entity" entity="gender" required="true"/>
<property name="neutered" type="boolean" default="false"/>
<property name="species" type="entity" entity="species" required="true"/>
<property name="breed" type="entity" entity="breed"/>
<property name="is-pedigree" type="boolean" default="false"/>
<property name="pasture" type="entity" entity="pasture"/>
<property name="history" type="link" entity="event"/>
</entity>
<entity name="gender" magnitude="1" volatility="10">
<key>
<property name="gender" type="string" size="8" distinct="all" immutable="true">
<documentation>
Not confident of this. It might be better to store a single character (or even
boolean), because for i18n reasons storing a natural language token is going
to make data from different systems non-comparable.
</documentation>
</property>
</key>
</entity>
<entity name="species" magnitude="2" volatility="5">
<key>
<property name="species" type="string" size="32" distinct="all" immutable="true">
<documentation>
Store scientific/latin name for species. TODO: 32 characters may not be enough.
</documentation>
</property>
</key>
</entity>
<entity name="breed" magnitude="1" volatility="10">
<key>
<property required="true" type="integer" name="id"
column="id" immutable="true" distinct="system">
<generator action="native"/>
</property>
</key>
<property name="breed" type="string" size="32" distinct="all" immutable="true">
<documentation>
Is there a canonical name for a breed? Is a Texan 'Galloway' the same breed
as a Galloway 'Galloway'? What even is a breed? Should we store details of
a breed society or other body which adjudicates membership of the breed?
</documentation>
</property>
<property name="species" type="entity" entity="species"/>
</entity>
<entity name="event" magnitude="9" volatility="2">
<key>
<property required="true" type="integer" name="id"
column="id" immutable="true" distinct="system">
<generator action="native"/>
</property>
</key>
<property name="type" type="entity" entity="event-type"></property>
<property name="actor" type="entity" entity="user-account" required="true" immutable="true">
<documentation>The user who recorded this event.</documentation>
</property>
<promperty name="date" type="timestamp" required="true" default="now()"/>
<property name="pastures" type="link" entity="pasture">
<documentation>Pastures affected by this event.</documentation>
</property>
<property name="animals" type="link" entity="animal">
<documentation>Animals affected by this event.</documentation>
</property>
<property name="summary" type="string" size="80"/>
<property name="notes" type="text"/>
</entity>
<entity name="event-type" magnitude="3" volatility="5">
<key>
<property required="true" type="integer" name="id"
column="id" immutable="true" distinct="system">
<generator action="native"/>
</property>
</key>
<property name="summary" type="string" size="80" distinct="user"/>
<property name="description" type="text"/>
<property name="n-holdings" type="integer" default="1">
<documentation>
Number of holdings affected by this event type; if an animal movement on
or off, for example, it will be two, otherwise normally one.
</documentation>
<prompt prompt="No. of Holdings Affected" locale="en_GB.UTF-8"/>
</property>
<property name="n-pastures" type="integer" default="1">
<documentation>
Number of pastures affected by this event type; if an animal movement between
pastures, for example, it will be two, otherwise normally one.
</documentation>
<prompt prompt="No. of Pastures Affected" locale="en_GB.UTF-8"/>
</property>
<property name="n-animals" type="integer" default="1">
<documentation>
Number of animals affected by this event type. If a value greater than 10
is recorded, that will be treated as 'many'. TODO: not comfortable that
that is the right way to handle 'many'.
</documentation>
<prompt prompt="No. of Animals Affected" locale="en_GB.UTF-8"/>
</property>
</entity>
<entity name="user-account" magnitude="6" volatility="3">
<key>
<property required="true" type="string" name="username" size="32"
column="username" immutable="true" distinct="all"/>
</key>
<property required="true" type="string" name="fullname"
column="fullname" size="64" distinct="user">
<prompt prompt="fullname" locale="en_GB.UTF-8"/>
</property>
<property name="avatar" type="image" size="256">
</property>
<property name="bio" type="text">
<documentation>Information the user supplies about themselves; an introduction.</documentation>
<prompt prompt="Bio" locale="en_GB.UTF-8"/>
</property>
<property type="string" name="phone" column="phone" size="16"
distinct="user">
<prompt prompt="phone" locale="en_GB.UTF-8"/>
</property>
<property type="string" name="email" column="email" size="128"
distinct="user">
<prompt prompt="email" locale="en_GB.UTF-8"/>
</property>
<!-- property required="true" type="entity" name="authority_id"
entity="authorities" farkey="id">
<prompt prompt="authority_id" locale="en_GB.UTF-8"/>
</property -->
<property type="boolean" name="authorised" column="authorised">
<prompt prompt="authorised" locale="en_GB.UTF-8"/>
</property>
</entity>
</application>