Reports and emails as document kinds, the two stages #133 deferred #162

Closed
opened 2026-09-10 06:08:11 +00:00 by tiagoagueda · 0 comments
Owner

Observation

#133 asks for five document kinds and proposes doing them in three stages, in this order:

Portfolios need the polymorphic link and the theme rule and nothing else. Reports need
those plus a decision about a computed document. Emails need a boundary drawn with
notifications. Doing them in that order means each answer is checked by something
shipping, rather than all of it being designed at once.

Stage one shipped with #133. This is stages two and three, kept apart because they turn
on two different unanswered questions.

What exists after #133

  • The kind vocabulary is one registry. documents/kinds.py says what each kind is,
    whether Postulo composes one, and which theme vocabulary sets it. The kind columns take
    their choices from it through a callable, so a kind a plugin registers reaches every
    picker and every store's per-kind switch with no migration.
  • Portfolios exist, as a CVKind on the model that already selects from the career
    record, with their own theme vocabulary and a shipped theme in each family.
  • Stores no longer ask what a document is. A holder declares download_url_name,
    archive_origin and archived_at; a third thing that holds a file needs no branch in
    stores.py at all, and there is a test proving it with a class stores.py has never
    heard of.

So the polymorphic link, the theme rule and the vocabulary are all in place. What is left is
the two kinds whose content raises a question the machinery does not answer.

Reports

Most of this is already answered. #56 shipped the report — the period, the cadence, the
evidence list, the PDF and the CSV — and settled the hard part in advance:

Nothing is stored. A report is computed when it is asked for, from records that are
already the truth, which is what makes it a snapshot of the record at a moment — and why
"edit this document" never has to mean anything for this kind.

What adopting it as a kind would add is the delivery half: a report that has been produced
becomes a RenderedDocument filed under a report kind, and is therefore copied to a
Paperless the way a CV is. A report handed to an employment office is exactly the document
somebody would want filed.

The question to settle first: a report snapshot and a report page are not the same
thing, and freezing one on every view would fill the store with near-identical PDFs. Is a
report frozen when somebody presses Download PDF, or never? The first is probably right —
that is the moment it becomes evidence somebody handed over — but it should be decided
rather than assumed.

Emails

This is the one that is genuinely undecided, and #133 says so:

An email that is a document is something composed, rendered, frozen and copied to a
store; an email that is a message is something a transport carries. Which of those this
kind is decides whether it belongs in documents at all, and the answer is not obvious.

Two more things worth having in view when it is decided:

  • #104 locks the transport when it is the last way back into an account. A kind that
    composes mail and a transport that carries it are not the same concern, and conflating
    them would put a document feature behind an account-recovery lock.
  • The useful part may already exist. What is worth keeping about an email to a recruiter
    is what RenderedDocument already does for a letter: the text as sent, frozen, with a
    checksum. A follow-up note is already a LetterKind, and it is an email in all but
    name.

So the smallest honest version might be: no email kind at all, and instead a way to
freeze what was actually sent through a transport as a rendered document. That is worth
considering before a fifth kind is built.

Worth being careful about

The wide contract #133 describes is still not built, deliberately. A kind that declares
a model, a template per theme, a starter, how it renders and how it snapshots would be a
much larger surface than any other plugin kind here — and most of it already lives somewhere
better: a theme declares its own templates (#132), a LETTER_STARTERS-shaped map declares
what a new one starts as, rendering goes through documents.rendering. Building that surface
before anything outside asks for it would be designing against a guess. documents/kinds.py
answers the part that was actually missing and says this in its docstring.

Classification

Enhancement, for 0.4.0. Two kinds, and the reports half is much closer than the emails half.

Depends on

#133 (done). #56 for the report content (done).

## Observation #133 asks for five document kinds and proposes doing them in three stages, in this order: > Portfolios need the polymorphic link and the theme rule and nothing else. Reports need > those plus a decision about a computed document. Emails need a boundary drawn with > `notifications`. Doing them in that order means each answer is checked by something > shipping, rather than all of it being designed at once. **Stage one shipped with #133.** This is stages two and three, kept apart because they turn on two different unanswered questions. ## What exists after #133 - **The kind vocabulary is one registry.** `documents/kinds.py` says what each kind is, whether Postulo composes one, and which theme vocabulary sets it. The `kind` columns take their choices from it through a callable, so a kind a plugin registers reaches every picker and every store's per-kind switch with no migration. - **Portfolios exist**, as a `CVKind` on the model that already selects from the career record, with their own theme vocabulary and a shipped theme in each family. - **Stores no longer ask what a document is.** A holder declares `download_url_name`, `archive_origin` and `archived_at`; a third thing that holds a file needs no branch in `stores.py` at all, and there is a test proving it with a class `stores.py` has never heard of. So the polymorphic link, the theme rule and the vocabulary are all in place. What is left is the two kinds whose *content* raises a question the machinery does not answer. ## Reports **Most of this is already answered.** #56 shipped the report — the period, the cadence, the evidence list, the PDF and the CSV — and settled the hard part in advance: > Nothing is stored. A report is computed when it is asked for, from records that are > already the truth, which is what makes it a snapshot of the record at a moment — and why > "edit this document" never has to mean anything for this kind. What adopting it as a *kind* would add is the delivery half: a report that has been produced becomes a `RenderedDocument` filed under a report kind, and is therefore copied to a Paperless the way a CV is. A report handed to an employment office is exactly the document somebody would want filed. **The question to settle first:** a report *snapshot* and a report *page* are not the same thing, and freezing one on every view would fill the store with near-identical PDFs. Is a report frozen when somebody presses *Download PDF*, or never? The first is probably right — that is the moment it becomes evidence somebody handed over — but it should be decided rather than assumed. ## Emails **This is the one that is genuinely undecided**, and #133 says so: > An email that is *a document* is something composed, rendered, frozen and copied to a > store; an email that is *a message* is something a transport carries. Which of those this > kind is decides whether it belongs in `documents` at all, and the answer is not obvious. Two more things worth having in view when it is decided: - **#104 locks the transport when it is the last way back into an account.** A kind that composes mail and a transport that carries it are not the same concern, and conflating them would put a document feature behind an account-recovery lock. - **The useful part may already exist.** What is worth keeping about an email to a recruiter is what `RenderedDocument` already does for a letter: the text as sent, frozen, with a checksum. A *follow-up note* is already a `LetterKind`, and it is an email in all but name. So the smallest honest version might be: **no email kind at all**, and instead a way to freeze what was actually sent through a transport as a rendered document. That is worth considering before a fifth kind is built. ## Worth being careful about **The wide contract #133 describes is still not built, deliberately.** A kind that declares a model, a template per theme, a starter, how it renders and how it snapshots would be a much larger surface than any other plugin kind here — and most of it already lives somewhere better: a theme declares its own templates (#132), a `LETTER_STARTERS`-shaped map declares what a new one starts as, rendering goes through `documents.rendering`. Building that surface before anything outside asks for it would be designing against a guess. `documents/kinds.py` answers the part that was actually missing and says this in its docstring. ## Classification Enhancement, for 0.4.0. Two kinds, and the reports half is much closer than the emails half. ## Depends on #133 (done). #56 for the report content (done).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Postulo/postulo#162
No description provided.