phase-5: declarations, from generated numbers to a PDF you file yourself
Formulario 120 and 515 assembly, the review screen, approval, the PDF, and the guided checklist that walks the user through presenting it in Marangatu. Approval is a promise about what the user actually saw: the numbers are recomputed on the way in, and if the documents moved since the declaration was generated the answer is a 409 with the fresh figures stored as a draft, not a silent approval of numbers nobody read. An approved declaration is never regenerated or invalidated. Editing, confirming, rejecting or reclassifying a document flips any ready declaration covering its period back to draft, which is what the dashboard reads to stop offering it for review. The PDF is rendered once and cached against the declaration, so two downloads are byte for byte the same document; every write that changes the numbers clears the cache. Approval pre-renders it, and the route renders on demand, so a failed job costs a wait rather than a missing file. It stays Spanish in both locales, like the form it mirrors, and carries a BORRADOR watermark until it is approved. The seeded declarations are computed through the same code path the product uses, so their figures agree with the documents behind them. Three defects the screenshots caught: the floating scan button swallowed the tap meant for Aprobar on a phone, the summary breakdown reused labels meant for other screens, and five tab labels collided at 390px. Tests that can avoid depending on a fresh seed now do; the ones that cannot say so in the assertion rather than timing out. db:reset warns that the API has to be stopped first, having learned that the hard way. 293 vitest tests, 59 Playwright tests, rules coverage still 100%, typecheck and lint clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
5dc284c5f2
commit
6620650e9e
+84
-1
@@ -441,7 +441,14 @@ The suite also erodes the seed it runs against: after a run, documents that star
|
||||
bandeja are confirmed and insights are dismissed, so the next run is not the same run.
|
||||
`pnpm db:reset` rebuilds the local database from the migrations and the seed, and the
|
||||
README says to use it before an e2e run. It refuses to touch anything but a local SQLite
|
||||
file, because it is destructive by definition.
|
||||
file, because it is destructive by definition, and it warns that the API has to be stopped
|
||||
first: deleting a file the running process holds open leaves it writing to an inode nothing
|
||||
else can see, which looks like half the suite breaking at once.
|
||||
|
||||
Where a test can avoid depending on a fresh seed, it does. Golden path 4 generates its own
|
||||
declaration for a month that has documents and no declaration yet, because approving is a
|
||||
one way door. The ones that genuinely cannot, like scanning into an empty bandeja, say so
|
||||
in the assertion message rather than timing out on a locator.
|
||||
The dashboard's insight test self-skips once every insight for that account has been
|
||||
dismissed, since dismissals persist by design; the persistence guarantee itself is asserted
|
||||
against the API from a fresh database.
|
||||
@@ -453,3 +460,79 @@ against the API from a fresh database.
|
||||
obtains one is not in v1 scope.
|
||||
- **Declarations.** `declaration_ready` is in the next-action priority and the sweep reads
|
||||
from it, but nothing sets a declaration to `ready` until phase 5.
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Phase 5
|
||||
|
||||
### A generated declaration is `ready`, and approval is a promise about what was seen
|
||||
Generating assembles the numbers and marks them `ready`: settled, waiting for a person to
|
||||
agree. Approving recomputes them first, and if the documents moved in between it returns a
|
||||
409, stores the new figures as a `draft`, and asks the user to look again. Approving
|
||||
figures nobody saw is the one outcome that must be impossible, and it is the reason the
|
||||
recompute happens on the way in rather than at render time.
|
||||
|
||||
An approved declaration is never regenerated or invalidated. Once a person has put their
|
||||
name to a set of numbers, rewriting them behind their back is worse than any staleness.
|
||||
|
||||
### A document that moves invalidates the declaration that counted it
|
||||
CONTRACTS.md 5.4. Confirming, rejecting, editing or reclassifying a document flips any
|
||||
`ready` declaration covering its period back to `draft`, which is what the dashboard reads
|
||||
to stop offering it for review. The month decides for a 120 and the year for a 515.
|
||||
|
||||
### The PDF is cached against the declaration, not regenerated per download
|
||||
Two downloads of the same declaration are byte for byte the same document, which matters
|
||||
when someone is transcribing from a printout. Every write that changes the numbers clears
|
||||
`pdf_file_id`, which is what makes the cache safe. Approval enqueues a render so the
|
||||
download on the success screen is instant; the route renders on demand too, so a failed
|
||||
job costs a wait rather than a missing document.
|
||||
|
||||
### The form preview and the PDF stay Spanish in both locales
|
||||
FLOWS.md section 1 and the COPY.md policy. The casilla labels mirror the DNIT form, and a
|
||||
form whose labels have been translated is harder to transcribe from, not easier. The
|
||||
caption around the preview says so in the reader's language. Two strings are hoisted out
|
||||
of JSX with the reason written down, because the inline copy lint rule is right to flag
|
||||
them and the answer is a comment, not an exception.
|
||||
|
||||
### The platform never files anything
|
||||
Flow D3 is a checklist, not a submission: numbered steps, every casilla one tap from the
|
||||
clipboard, and "Ya la presente" as the user telling us rather than us finding out. Marking
|
||||
filed is only possible after approval, because the checklist is what follows approval.
|
||||
|
||||
### The seeded declarations are computed, not written down
|
||||
CONTRACTS.md section 4 asks for a ready F120 for the previous month and an approved one two
|
||||
months back. Both are assembled through the same code path the product uses, so their
|
||||
figures agree with the documents behind them. A fixture whose numbers disagreed with its
|
||||
own documents would be worse than no fixture.
|
||||
|
||||
### The declarations tab joined the shell
|
||||
Five tabs now. Vencimientos stays reachable from the dashboard's deadline card and its
|
||||
overdue action, so nothing lost a route.
|
||||
|
||||
### A test that had to grow
|
||||
The next-action priority test now walks two rungs of the ladder rather than one: with the
|
||||
seeded `ready` declaration in place, `declaration_ready` correctly outranks `bandeja`, and
|
||||
the test approves it to check the fall through. The 5.4 test clears the outstanding
|
||||
periods first, because `overdue` outranks everything and Maria has never filed a 515.
|
||||
|
||||
### Three defects the screenshots caught
|
||||
**The scan button swallowed the tap meant for "Aprobar".** The floating button and the
|
||||
sticky approve footer overlap on a 390px screen, and the desktop e2e never saw it because
|
||||
the viewport is wider. The button now appears on the screens you arrive at, not on a detail
|
||||
screen that has its own primary action, and a test asserts it.
|
||||
|
||||
**The summary breakdown was mislabelled.** It called the debito "A pagar" and the saldo
|
||||
anterior "Casilla", because it reused keys meant for other screens. Three labels of its own
|
||||
now.
|
||||
|
||||
**Five tab labels collided at 390px.** Smaller, truncating labels rather than dropping a
|
||||
tab, since every one of them is a place the user needs to reach.
|
||||
|
||||
### Deferred, deliberately
|
||||
- **Motion.** The confetti on approval and the canvas moment on the filed screen are
|
||||
FLOWS.md D3; the motion pass and the canvas touches are phase 7. The screens are built
|
||||
with the right structure and states.
|
||||
- **Payment reminders after filing.** FLOWS.md D3 mentions scheduling one on "Ya lo
|
||||
presente". The deadline sweep already covers T-2 and T-0 for the period; a separate
|
||||
payment date is not in RULES.md and was not invented.
|
||||
|
||||
Reference in New Issue
Block a user