Skip to main content

audittemplates

One row per audit template — the reusable blueprint that audits are instantiated from. Identified by id; lives on a single project.

Source Mapping

CouchDB document type: an "audittemplate" document (see asyncconvert.py's audittemplates(obj) handler).

ColumnCouchDB sourceNotes
ididTemplate identifier; unique within the dataset across projects (project-scoped semantics — see Pitfalls).
namenameHuman-readable template name. Free text.
groupidgroupIdThe template_groups.id this template belongs to. May be empty when the template is ungrouped.
groupnamegroupDenormalized group name from source — convenient but can drift from template_groups.name.
authorauthor.emailEmail of the user who authored the template.
lastmodifierlastmodifier.emailEmail of the user who last edited the template.
creationdatedates.creationDateParsed via parseDate(...).
lastmodifieddatedates.lastModifiedDateParsed via parseDate(...).
archivedarchivedParsed via parseDate(...). NULL for active templates.
statuscomputed (derived)'published' when isPublished in source is truthy, otherwise 'draft'. The default in the schema is 'draft'.
projectiddatabaseThe project this template belongs to.
couchdbidcouchDbIdLegacy CouchDB document identifier.

Column Reference

ColumnTypeNullableDescription
archivedDATETIMEyesArchive timestamp; NULL for active templates.
authorVARCHAR(255)yesEmail of the user who authored the template.
creationdateDATETIMEyesWhen the template was created upstream.
lastmodifieddateDATETIMEyesWhen the upstream template was last edited.
groupidVARCHAR(255)yesForeign-key reference to template_groups.id.
groupnameVARCHAR(255)yesDenormalized group name; convenience copy of template_groups.name from source.
nameVARCHAR(255)yesHuman-readable template name. Free text — may vary in spelling across projects.
lastmodifierVARCHAR(255)yesEmail of the user who last edited the template.
statusVARCHAR(20)yesLifecycle state: 'draft' or 'published'. Defaults to 'draft'.
idVARCHAR(255)noPrimary key. Template identifier; project-scoped (see Pitfalls).
projectidVARCHAR(255)yesThe project this template belongs to.
couchdbidVARCHAR(255)yesLegacy CouchDB identifier.

Keys

  • Primary key: id

Indexes

  • idx_project on projectid
  • idx_status on status

Relationships

DirectionOther tableJoinCardinality
outgoingtemplate_groupsaudittemplates.groupid = template_groups.idmany templates → one group
outgoingprojectsaudittemplates.projectid = projects.idmany templates → one project
outgoingusers (author)audittemplates.author = users.emailmany templates → one author
outgoingusers (lastmodifier)audittemplates.lastmodifier = users.emailmany templates → one user
incomingauditsaudits.template = audittemplates.idone template → many audit instances

None of these are foreign-keyed in MariaDB; joins are by string match.

Refresh Semantics

A row is upserted when its template document is observed in source data, and replaced on subsequent observations. Archive is a soft state: the archived DATETIME is set when the template is archived upstream, but the row is not removed and existing audits that reference it continue to resolve.

A reindex with type=audittemplate (or a full reindex) drops the audittemplates table and rebuilds it from source. See backend/services/sql.py for the drop and setup paths.

Common Queries

List published templates on a project

SELECT id, name, groupname, creationdate
FROM audittemplates
WHERE projectid = 'your_project_id'
AND status = 'published'
AND archived IS NULL
ORDER BY name;

Find draft templates that have not been touched recently

SELECT id, name, author, lastmodifieddate
FROM audittemplates
WHERE status = 'draft'
AND archived IS NULL
AND (lastmodifieddate IS NULL OR lastmodifieddate < (NOW() - INTERVAL 60 DAY))
ORDER BY lastmodifieddate;

Templates by author

SELECT
author,
COUNT(*) AS templates,
SUM(CASE WHEN status = 'published' THEN 1 ELSE 0 END) AS published
FROM audittemplates
WHERE archived IS NULL
GROUP BY author
ORDER BY templates DESC;

Cross-table queries (template usage by audits, templates by group) live on the Audit Templates domain landing.

Pitfalls

  • id is project-scoped, not global. Two projects each with a "Quality Inspection" template produce two audittemplates rows with two different id values. Joining on id does not give you cross-project usage — group by name for that. See the domain landing.
  • status is a string, not a boolean. Values are 'draft' or 'published' (and the schema default is 'draft'). Compare with string equality, not boolean operators. Source's isPublished is flattened into this string before insert.
  • groupname can drift from template_groups.name. It is a denormalized copy from source. If the group is renamed, the authoritative value is template_groups.name; groupname may lag until the template document is re-synced.
  • No FK constraints. groupid, projectid, author, and lastmodifier are joined by string match. If an upstream group is deleted without templates being re-synced, groupid may point to a missing template_groups row.