Vibecode Rescue: finpacto.com
Three legal documents that agree with each other on a four-day deletion window, and no way to email anyone about them. 60/100 — Fragile.
finpacto converts PDF bank statements into Excel, CSV or TOCOnline format. It's Portuguese, it's aimed squarely at accountants, and the pitch is the least glamorous and most honest in this batch: you are copying bank statements into spreadsheets by hand, that costs you hours a month, upload the PDF instead. Plans run free at 2 pages a month, €19.9 Pro, €39.9 Expert, €99.9 Enterprise.
It scored 60 out of 100. Fragile, by exactly one point.
Observed on 2026-08-05 against a snapshot of the page, the shipped bundle, response headers, DNS, and the three legal documents rendered in a real browser. No account was created.
Three documents that agree
I spend most of this series pointing at documents that contradict each other. So: the Terms, the Privacy Policy and the dedicated RGPD page all state the same retention rule, in the same terms, without drift.
Termos §7: Todos os extractos bancários processados são automaticamente excluídos após 4 dias.
Privacidade §3: Os extractos bancários processados são automaticamente excluídos após 4 dias.
RGPD §6: Extratos bancários processados: automaticamente eliminados após 4 dias.
Four days, three times, three documents. The Terms then do the thing that makes the promise operational rather than decorative — they tell the user what the deadline means for them: download your converted statements inside the window, because after it they're gone and we're not responsible for that.
The RGPD page is the strongest single legal document in this batch of ten. It names the legal bases per purpose, sets billing-record retention at ten years to match Portuguese tax law, states that data is stored on EU servers with standard contractual clauses if it ever leaves, enumerates all eight data-subject rights, and points complaints at the CNPD — the Portuguese supervisory authority — by name.
For a product whose entire job is to receive other people's bank statements, that's the right shape. It's also, bluntly, better than what several funded companies publish.
And no way to contact anyone about them
=== EMAIL ADDRESSES PUBLISHED ===
none found on the collected surfaces
Not one address. Not on the homepage, not in the Terms, not in the Privacy Policy, not on the RGPD page. Every one of those documents routes the reader to the same place:
Para exercer qualquer um destes direitos, contacte-nos através do formulário de contato no nosso website.
A contact form on the homepage. That's the only channel, and it's the channel for all eight GDPR rights, for the DPO, and for the complaint that comes before the CNPD complaint.
Then section 13 of the RGPD page, headed "Contato e Encarregado de Proteção de Dados (DPO)", names no DPO. It's a heading with a form under it.
And the controller has no identity. "O finpacto é o responsável pelo tratamento" — finpacto is the controller — where finpacto is a brand. The company name, the NIF and the registered address are all missing from a document written specifically to satisfy a regulation that requires the controller's identity and contact details. The domain has working Google MX records, so a mailbox is available; nobody published an address at it.
That's the third product in this batch to write careful policy and skip the identity. The pattern is consistent enough to be worth stating plainly: generated legal documents get the sections right, because sections are what a template knows. Who you are, where you are, and how to reach you are the fields a template can't fill, and they're the fields that turn a policy into something a person can act on.
Every URL is 200, including the sitemap
$ curl -o /dev/null -sw '%{http_code}\n' https://finpacto.com/seams-audit-does-not-exist-20260805
200
$ curl -s https://finpacto.com/sitemap.xml | head -c 60
<!doctype html><html lang="pt"><head><meta charset="UTF-8"
Every path returns the 2 KB app shell, so /privacy, /terms, /rgpd and an invented path all come back 200 — the real documents render only after the JavaScript executes. And /sitemap.xml serves HTML, which means the site has no sitemap while passing every automated check that one exists.
robots.txt is served properly at 160 bytes, so the SPA is answering one of those two correctly and not the other.
The practical cost lands on A5. This is a product with a narrow, high-intent search market: Portuguese accountants looking for "converter extrato bancário para Excel". It is serving search engines an HTML document where the sitemap should be.
The browser talks to the database
https://kdflwpqbnigyscmbbjyw.supabase.co
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…
Supabase project URL and anon key in the bundle. Public by design; row-level security is what stands between it and the tables, and that's invisible from outside. Unknown, 5.5 of 11.
The data class is what makes this the most interesting Unknown in the batch. The tables behind that key hold uploaded bank statements — account numbers, balances, every transaction a Portuguese small business made last month, uploaded by accountants on behalf of clients who have never heard of finpacto. The four-day deletion window shrinks the exposure honestly, and that's a real mitigation. It doesn't answer whether one accountant's rows are reachable by another's session.
A note on something I nearly reported
The "how much time do you lose" section rendered, in my headless capture, as "8-0h por mês", "0% taxa de erro" and "€ 0+ custo mensal" — broken counters, and a tempting finding.
It isn't one. The bundle uses IntersectionObserver to drive count-up animations, and a headless dump that never scrolls never triggers them. A real visitor scrolling the page sees real numbers. The defect was in my collector, not their product, and it's in this writeup because the rule is that a number needs a file behind it — including the numbers that would have made a better story.
What it gets right
- The legal surface, described above: three consistent documents, a named supervisory authority, real retention periods, EU-only storage.
- Lighthouse 12 desktop: performance 89, accessibility 96, best practices 100, SEO 100. 0.8 MB, 1.3-second paint. Only one product in this batch is faster.
-
Four of six security headers: HSTS,
X-Frame-Options: DENY,X-Content-Type-Options: nosniff, Referrer-Policy. CSP and Permissions-Policy are the gaps. - SPF is published and Google MX resolves.
- The pricing is unusually honest about the trial. "Cartão necessário" — card required — is stated directly under the trial button, twice, rather than discovered at checkout. One product in the previous batch of five called a $1 charge a free trial; this one calls a real free trial what it is and tells you the card comes first.
- The positioning is specific to a real job: TOCOnline output, supplier invoices as well as statements, bulk upload, per-client organisation. Written by someone who knows what a Portuguese accountant's week looks like.
The engineering underneath
DMARC is p=none — monitor-only. On a domain that receives bank statements, moving to quarantine is cheap insurance against someone forging a "please send this month's statements to…" message.
The three testimonials are attributed to named accountants with specific claims — 10 hours a week saved, 200+ statements a month, "reduziu erros a zero". Unverifiable from outside, which is normal, and worth a line only because "errors reduced to zero" is a strong claim to put in someone else's mouth on a page selling conversion accuracy, while the Terms say the opposite three screens later: no guarantee conversions are 100% accurate, check them yourself.
The score
Sixty exactly — one point into Fragile, which is a fair description. The documents are better than the average funded startup's. The way you reach the people behind them is worse than the average side project's.
What I'd fix first
-
Publish an email address.
privacidade@finpacto.comin the three policies and in the footer. The MX records already work. Every GDPR right you enumerate currently terminates in a web form. - Name the entity. Company name and NIF in the RGPD page and the Terms. The controller is legally a person or a company, never a brand.
- Name a DPO or drop the heading. Section 13 promises one and doesn't have one; either is fine, the mismatch isn't.
-
Serve a real
sitemap.xmland return 404 for paths that don't exist. Your search market is narrow and high-intent; you're currently invisible to half of it. -
Add a CSP, and move DMARC to
quarantine.
Disclosure
Findings went to the operator before this published. These audits are free and public; the paid version is a Code Health Check, and the rescue work after it is Track 03 on my services page.
One dimension scored Unknown and code access resolves it: whether row policies are enforced on the tables holding uploaded statements during the four days they exist.