Skip to content
undan

Help › Facts

Facts

Every document has facts: its type, its tags, typed fields (amount, due date, IBAN, …) and notes. They are created in the Inbox, from e-invoices, from checked patterns, in the chat and by hand — and they are what the search field filters by and what its table shows in columns.

The fact sheet of the preview

Type, actions, tags#

QuestionValuesHow many
TypeWhat is it?invoice, medical-invoice, receipt, letter, …exactly one
ActionsWhat needs to be done with it?Pay, Bookkeep, Submit, … — each to do, done on or not neededas many as concern the document
TagsWhat does it belong to?free: egge-ctf, marlene, …any number

A tag no longer carries a state. What is to be done is an action on the document — and only there: a task points to the document and holds no copy of it. A paid invoice is type Invoice (invoice) with Pay: done on 04.10.2026; one that is debited automatically has Pay: not needed. A due date is a date on the document and does not change when you pay.

Not needed or the cross? not needed is a decision: the action stays on the document and counts as done without you doing anything — the search finds it with $pay:skipped. The cross at the end of the row takes the action off the document, as if it had never concerned it; afterwards a search like type:invoice missing:$pay finds it again. In the fact sheet and on the side panel of the Mail tab the cross only shows while the pointer is over the row or the keyboard is in it (Tab reaches it); in the Inbox form it is always there.

On top of that there are fields with a fixed type (money, date, text) — which ones a document shows is decided by its type — and notes, which are appended: each one a line with a timestamp, together a history.

Where a value comes from#

Every value carries its source, and it can be seen in the fact sheet:

SourceMeaning
userset by hand — always wins
inboxcomputed when applying in the Inbox — such as origin on a document from an email
chatsuggested by the model, accepted in the proposal card
zugferdfrom the XML of an e-invoice
regexfound by pattern and checked against the checksum (IBAN, OCR number)
claude:haikuread out by the model, without acceptance per value
vorbelegung:…a tag from a preset in the vocabulary
button:View/Buttona button in a view

The order when writing: user before zugferd before regex before claude. A model value never overwrites what you have set yourself; a checked value (an IBAN with a valid checksum) wins over a guessed one.

Editing#

  • The fact sheet of the preview — in the Documents tab, in the chat, in Tasks. Above every preview is the fact bar with the essentials — the type as a chip, the payee, the amount, the deadline, what is to be done, the reminder ("Reminder · Wed 9:00", with the reminder's symbol; "· if no reply" when it only comes if there is no reply), the tags; a click on the pencil on the right (or on the row, or Alt+6) expands the sheet. Inside: the type as a selection, What is to be done with the reminder (the chip Reminder · Tue 9:00, without a reminder Remind … — a click opens the same field as in the Mail tab), the fields of the type, for invoices the Payment with a GiroCode to photograph, tags, notes.
  • Next to or below the document — you decide with the toggle to the left of the pencil (only when the sheet is open). The choice applies to all previews; the sheet doesn't switch by itself, even when the preview becomes narrow.
  • Save — the sheet collects your changes until you save: changed values carry the mark changed, the bar says "n unsaved", and above the sheet there are Discard and Save. Ctrl+S saves when the keyboard is in the sheet — including a field you are typing in right now. Everything together is one step: one Ctrl+Z takes it back. If you switch files with unsaved changes, the app asks: Save, Discard or Keep — then the draft waits on the file until you come back (until the app quits).
  • While the table is being edited (Ctrl+E in the table), the sheet is read-only — the changes then belong in the table.
  • Tags — the input suggests what already occurs in the archive, most frequent first; Return takes the first match or a new name.
  • "+ Action" stays open until you press Esc or click elsewhere — so you can add several actions one after another. "+ Field" lists the fields alphabetically.
  • Empty fields — the fields with a value are at the top; the type's empty fields sit below them, collapsed behind "Empty fields (7)" (the number says how many). A click, Return or the space bar expands them; when open, Tab leads into them. The choice applies to every document until you quit the app. If a document has no value at all yet, they are open by themselves. "+ Field" offers the collapsed ones too — once chosen, the field shows at the top. An empty field is never saved; the Inbox form still shows all fields of the type.
  • Where a value comes from is shown in small print below the field name — only for values that are not yours. What you enter yourself wins; a model never overwrites it.
  • Notes can be corrected: click the note, change the text, leave the field or Ctrl+Return (and then save). The old version stays in the history.
  • From the page — every field has a button Take from the page: click the field, then drag a region in the document; the text lands in the field, in the stored format.
  • The calendar — every field of type date (due date, invoice date, paid_on, …) has a calendar icon next to it. It opens a month sheet right at the field, set to the value that is in the field — otherwise to today —; ←→ day, ↑↓ week, Return chooses, Esc closes. The choice writes the date into the same field, in the format that is already used there (15.09.2026). Typing still works: the calendar is a second way, not a replacement.
  • Many documents at once — the edit mode of the table (Ctrl+E, see Documents).
  • The Inbox prefills the form on Read (source claude:<model>); nothing is written until Done.

Every save is one step: Ctrl+Z in the Documents tab takes it back. Nothing is deleted in the process; a counter-line is written instead — the history stays complete.

The vocabulary#

What a document is (type), what is on it (fields) and what needs to happen to it (actions) is in a text file:

<Dokumentenordner>/.undan/vocabulary.md
---
type: [invoice, medical-invoice, receipt, letter, other]
---
# Fields
- amount: money
- payee: text
- due: date „bis wann“

# Actions
- $pay
- $bookkeep
- $submit: „Bei der Kasse einreichen“

# States
- open
- done
- skipped
- reminder: „zurückgestellt“

# Types
- invoice:         payee, amount, due · $pay
- medical-invoice: payee, amount, due · $pay, $submit
- receipt:         payee, amount

The rules:

  • On the left is the key; the name comes from the language. Keys are English (payee, medical-invoice, $pay) and are stored like that in the journal; what the form, the fact sheet and the table show ("Payee", "Medical invoice", "Pay") comes from the catalog of the chosen language. A name of your own goes in „…" after it (- due: date „bis wann“, - $submit: „…“, for a type before the colon: - invoice „Faktura“: …) and takes precedence.
  • Header between ---: the list type. Names consist of lowercase letters, digits, _ and -. A type that has a line under # Types doesn't need to be listed here again.
  • # Fields: - name: type with money, date or text.
  • # Actions: - $key, with a name of your own - $key: „Display name“. The key starts with $ — that is how the app recognizes an action everywhere, even if the line is ever missing here —, is stored in the journal and never changes; you may change the name at any time without any value being lost. A new action is one line here; the form, the fact sheet and the search then know it. It opens nothing retroactively: "to do" is written at capture, never computed from the type. If you delete an action, it stays on the documents that carry it; the check strip says how many of them are still open. A date field without $ (such as paid_on from earlier times) is not an action, just a date.
  • # States: the states open (to do), done (done on), skipped (not needed) and reminder (Reminder). Their meaning is fixed. to do and done on always exist; if you leave out skipped or reminder, they are no longer offered — existing values stay readable. Without the section, all four apply.
  • # Types: - type: field, field · $action, $action — the template for capture. Before the · the fields the form shows, after it the actions the type brings along (with their key). A type without a line (or with an empty one) shows no fields and brings nothing along — + Field adds one on the individual document.
  • Tags are not listed here. They are free: every valid name is a tag, and the search field suggests what occurs in the archive. (A vocabulary that still has a line tag: […] stays strict as before — delete the line, and the tags are free. The same goes for area: and # Presets: neither exists in the default any more, but both are still read.)

Saved means in effect. Changes to vocabulary.md take effect with Ctrl+S at once — in the Inbox form, in the fact sheet, in the search field. (If you change the file with another program, you wait a minute at most.)

An older archive doesn't know actions yet. The Inbox then offers at the top Extend vocabulary (appends the three sections, everything of your own stays, Ctrl+Z takes it back) and after that Convert to actions for the documents that still carry open, hochladen or nachhaken — an old payment date in paid_on or uploaded_on moves into the action as "done on".

Renaming or removing a field#

Values are stored in the journal under the key. If you rename - due: date to - pay_by: date or delete the line, they stay under due — nothing is lost, but the form, the table and the search no longer know the old name. The check strip above the text says so: collapsed it only shows “⚠ 12 notes”, one click opens the list. Every note has three buttons:

  • Rename … — a new name (picked from the vocabulary or typed); the dialog tells you beforehand how many values move. If a document already has a different value under the new name, it stays untouched and is named afterwards. If the vocabulary doesn't know the new name yet, its line is added too.
  • Remove values — after a confirmation; nothing is deleted, the journal gets counter lines.
  • Into the vocabulary — writes the line back into the text, its type computed from the values (all dates → date, all amounts → money). It applies once saved.

What you did then shows at the top of the list, with Undo; the history can take it back too.

After saving, Undan asks. If a name that carries values disappears and exactly one of the same type is added, the list starts with the question “Renamed? due → pay_by” with Take the values along and No. Rename several fields at once and Undan doesn't ask — then you pick the target via Rename … yourself. The same holds for actions ($…) and your own contact fields. Remember to replace the old name under # Types as well — the check strip shows every line that still names it.

Where the facts are stored#

Facts are attached to the content of the document (its checksum), not to the path. Renaming and moving change nothing about them — not in another program either, and not on the second computer. A copy shares the facts with the original.

Notes have an ID#

For a note the content isn't enough: it changes with every save. So every note gets an ID — a line id: at the very top of its properties:

---
id: k7m2q
name: Keller
---

Its facts are attached to that. Renaming, moving, editing in Obsidian — the ID stays, and with it the note's type, actions and tags.

It is assigned when writing: when you create a note, when you save it in the editor, when one moves from the Inbox into the archive. For notes that are already in the archive, there is a button in Settings under "Vocabulary", "Add IDs to notes" — it says how many it affects, and Ctrl+Z in the Documents tab takes everything back. The app never touches a file for this by itself.

If you delete the id: line in the editor, the next save writes it back and says so in the status line. If it is deleted in another program and the note is also changed there, it gets a new ID at the next save — the old facts then no longer find their way to it. A copy of a note always gets an ID of its own; the original keeps its own.

They are stored as a journal in the documents folder:

<Dokumentenordner>/.undan/facts/2026-09.jsonl

One line per statement, with timestamp, source and computer name. The journal only grows; the current state is "the newest line per field". That is why it copes with synchronization: two computers that both write produce a union without conflict. If the folder runs through Syncthing, the facts are there on both computers.

The dot folder .undan/ is the only place in the documents folder that the app writes to itself. It is part of the content: back it up and synchronize it along with everything else.

What is not there but in the app's state folder (~/.undan/instances/<folder>/): the search index (cache/, can be rebuilt at any time), the editor drafts and the chat histories. Trash, History and bookmarks, on the other hand, are in the archive under .undan/.

If a file is rewritten in the same place (OCR, the edit window, another program), the facts are kept: the app remembers that the new content replaces the old. For a change by another program, the fact sheet shows "File changed since the facts were entered".