Skip to main content
All Docs
FeaturesPurple PepperUpdated April 8, 2026

Special Conditions Library

Special Conditions Library

The special conditions library lets agencies build a reusable set of clause templates that agents can select when generating tenancy agreements. Conditions are snapshotted at the point of attachment, so past agreements are never affected by library edits.

Overview

  • Library management — Admins create, edit, categorise, and archive conditions in Company Settings.
  • Agreement generation — Agents pick from the library or type freeform clauses during tenancy agreement generation.
  • Snapshot integrity — The clause text and title are copied to the tenancy term at selection time; subsequent library edits do not alter existing agreements.
  • Promotion — Freeform clauses typed inline can be saved back to the library for future reuse.

Database Schema

special_conditions

Org-scoped library of clause templates.

ColumnTypeDescription
idtext (UUID)Primary key
orgIdtextOrganisation scope
titletextShort label for quick selection
bodytextFull clause text included in the agreement
isTemplatebooleantrue = reusable template; false = one-off
categorytext (nullable)Optional grouping (e.g. pets, garden, parking)
sortOrderintegerDisplay order within the list
isActivebooleanfalse = soft-deleted / archived
createdByUserIdtextAudit trail — who created this entry
createdAt / updatedAttimestampTimestamps

tenancy_term_special_conditions

Junction table linking snapshotted conditions to tenancy terms.

ColumnTypeDescription
idtext (UUID)Primary key
orgIdtextOrganisation scope
tenancyTermIdtextThe tenancy term this condition belongs to
specialConditionIdtext (nullable)Reference to the library entry; null for freeform
titletextSnapshotted title at attachment time
bodytextSnapshotted clause body at attachment time
sortOrderintegerDisplay order within the agreement
isFromLibrarybooleantrue = selected from library; false = freeform inline
attachedByUserIdtextAudit trail — who attached this condition
createdAttimestampTimestamp

tRPC Router: specialCondition

All endpoints are protected by orgProcedure and automatically scope queries to the caller's organisation.

Library Management

specialCondition.create

Adds a new condition to the library.

const condition = await trpc.specialCondition.create.mutate({
  title: "No pets allowed",
  body: "The tenant shall not keep any animals or pets on the premises without prior written consent of the landlord.",
  isTemplate: true,
  category: "pets",
  sortOrder: 0,
});

Input

FieldTypeRequiredDescription
titlestring (1–200 chars)Short label
bodystring (1–10 000 chars)Full clause text
isTemplateboolean— (default true)Reusable template flag
categorystring (max 100 chars)Grouping label
sortOrderinteger ≥ 0— (default 0)Display order

specialCondition.list

Returns all active conditions for the org. Supports optional filters.

const conditions = await trpc.specialCondition.list.query({
  category: "pets",
  isTemplate: true,
  isActive: true,
  search: "pets",
});

Input (all optional)

FieldTypeDefaultDescription
categorystringFilter by category
isTemplatebooleanFilter by template flag
isActivebooleantrueInclude active/inactive records
searchstring (max 200 chars)Title substring search

Each result includes a usageCount field showing how many tenancy terms currently reference the condition.


specialCondition.getById

Fetches a single condition by ID.

const condition = await trpc.specialCondition.getById.query({ id: "<uuid>" });

Throws NOT_FOUND if the condition does not exist or belongs to a different org.


specialCondition.update

Edits an existing library condition. All fields are optional — only supplied fields are updated. Existing tenancy term snapshots are not affected.

await trpc.specialCondition.update.mutate({
  id: "<uuid>",
  title: "Updated title",
  body: "Updated clause text...",
  category: "garden",
  sortOrder: 2,
  isActive: true,
});

specialCondition.archive

Soft-deletes a condition by setting isActive = false. The record is retained for historical reference.

await trpc.specialCondition.archive.mutate({ id: "<uuid>" });

specialCondition.listCategories

Returns the distinct set of category strings currently in use for the org. Useful for populating filter dropdowns.

const categories = await trpc.specialCondition.listCategories.query();
// e.g. ["garden", "parking", "pets"]

Tenancy Term Attachment

specialCondition.attachToTenancyTerm

Attaches one or more conditions (library picks and/or freeform clauses) to a tenancy term. The title and body of each condition are snapshotted at this point.

await trpc.specialCondition.attachToTenancyTerm.mutate({
  tenancyTermId: "<uuid>",
  conditions: [
    {
      specialConditionId: "<library-uuid>", // from library
      sortOrder: 0,
    },
    {
      // freeform inline clause
      title: "Lawn maintenance",
      body: "The tenant must mow the lawn fortnightly.",
      sortOrder: 1,
    },
  ],
});

specialCondition.detachFromTenancyTerm

Removes a previously attached condition from a tenancy term.

await trpc.specialCondition.detachFromTenancyTerm.mutate({
  id: "<tenancy-term-special-condition-uuid>",
});

specialCondition.listForTenancyTerm

Returns all conditions attached to a specific tenancy term, ordered by sortOrder.

const attached = await trpc.specialCondition.listForTenancyTerm.query({
  tenancyTermId: "<uuid>",
});

specialCondition.reorderForTenancyTerm

Updates the sortOrder of conditions on a tenancy term to reflect a new display sequence.

await trpc.specialCondition.reorderForTenancyTerm.mutate({
  tenancyTermId: "<uuid>",
  orderedIds: ["<id-3>", "<id-1>", "<id-2>"],
});

specialCondition.saveToLibrary

Promotes a freeform clause (attached inline to a tenancy term) into the reusable library.

const libraryEntry = await trpc.specialCondition.saveToLibrary.mutate({
  tenancyTermSpecialConditionId: "<uuid>",
  category: "parking",
});

Workflow

  1. Admin setup — Navigate to Company Settings → Special Conditions and create clause templates, assigning titles, bodies, and categories.
  2. Agreement generation — When generating a tenancy agreement, the agent is presented with the library. They can search by category or keyword, select conditions, and add freeform clauses inline.
  3. Attachment & snapshot — Selected conditions are written to tenancy_term_special_conditions with the clause text frozen at that moment.
  4. Reordering — The agent can drag conditions into the required order before finalising the agreement.
  5. Promote freeform — If a freeform clause is useful for future agreements, the agent can save it to the library directly from the term view.

Audit Logging

All mutating operations emit an audit log entry:

ActionTrigger
special_condition.createdcreate
special_condition.updatedupdate
special_condition.archivedarchive
special_condition.attachedattachToTenancyTerm
special_condition.detacheddetachFromTenancyTerm
special_condition.saved_to_librarysaveToLibrary

Security

  • All endpoints use orgProcedure, enforcing row-level org scoping on every query.
  • No cross-org data leakage is possible — every query filters by orgId derived from the authenticated session.