- How should a finance app store money in the database?
- As integers in the currency minor unit -- cents, pence, bani -- in an INTEGER column, with the ISO 4217 code beside it. Cloudflare D1 is SQLite, so a REAL column is a binary float, and a balance you may one day have to defend in front of an auditor should not depend on whether 0.1 plus 0.2 rounds the way you hoped. Fabricate writes the Drizzle schema into worker/database/schema.ts, so you can check the column type it chose before a single row exists.
- What does a double-entry ledger look like in a generated app?
- Three tables carry it. An accounts table names the buckets. A transactions table holds the header: date, description, status. A postings table holds the two or more rows belonging to each transaction, each with an account reference and a signed amount, and the signed amounts for one transaction must sum to zero. Balances then become a query over postings rather than a mutable column somebody forgets to update. Ask for exactly that shape in your prompt -- the sample schema that ships in the template is a generic items table, not an accounting one.
- Can the finance website builder connect to Stripe?
- Yes. One of the app templates ships with the Stripe SDK, a subscriptions table, a payments table, and a webhook route that verifies the signature before it writes anything. Point a Stripe endpoint at the webhook path and subscribe to the checkout completion event, the customer subscription events, and both invoice outcomes. The secret key and the signing secret belong in the platform secrets manager rather than in a file, and neither one should ever be referenced from client code.
- Is a generated finance app PCI compliant?
- No application is compliant by itself. PCI DSS applies to you as the operator, and your obligations depend on how card data moves through your systems. What a generated app gives you to work with is a payment path that keeps card numbers out of it: a hosted checkout or an embedded element collects the card, the processor hands back identifiers, and your rows hold a customer id and a payment id instead of a card number. That arrangement is what an assessor asks about. Producing the attestation is still your job.
- How do I stop a payment webhook from being applied twice?
- Providers retry on any response they cannot confirm, so a handler that credits an account on delivery will eventually credit it twice. Put a unique index on the provider event id and insert that id in the same batched write that posts the ledger entry. If the constraint fires, the retry becomes a no-op and the money moves once. Specify this when you describe the billing flow: idempotency is a design decision, not something a model infers from the instruction to add payments.
- Can I build a portfolio tracker or market data view?
- Yes, and the outbound request belongs in the worker rather than the browser. Hono routes run at the edge, so a data provider key stays server side and one cached quote can serve many visitors instead of one request per page load. Hold instruments and holdings in D1, add a positions history table if you need to chart cost basis over time, and treat every provider payload as untrusted input that you map into your own columns rather than rendering straight through.
- What about audit trails and who changed what?
- Financial rows should be corrected, never edited. Model a reversal as a new posting that offsets the original, so the history stays legible, and keep a separate table recording actor, action, and timestamp for anything that moves money or changes a permission. The sessions table already records device, user agent, address, and a revocation reason, which covers the identity half of an audit entry. The business half -- what was attempted and what the system decided -- is yours to specify.
- How do I keep users out of each other's accounts?
- Passwords are hashed with bcrypt, sessions are signed tokens, and the sessions table supports expiry, revocation, and failed-login lockout. None of that scopes a query. Every financial table needs an owning identifier, and every read has to filter on the authenticated subject in one shared data-access layer rather than in each route by hand. D1 has no row-level security policy to fall back on, so the boundary is code, and you should be able to point at the file where it lives.
- Can a generated app handle multiple currencies?
- Yes, once you decide the rules. Keep the amount and its currency code together on every row, refuse to sum across currencies in SQL, and store the conversion rate you actually used on the transaction so that a report from last quarter does not quietly re-price when today rate moves. Rounding is the other half of the problem: choose a single convention, put it in one helper in the worker, and make the invoice and the report call that same helper rather than each rounding on its own.
- Do I own the code my finance app is built from?
- Yes. What you get is an ordinary Vite and React front end, a Hono worker, and a Drizzle schema -- files you can read, edit in place, or hand to an engineer without a translation layer. There is no proprietary runtime to reverse engineer later. That matters more here than in most verticals, because sooner or later somebody in diligence asks how a balance is computed, and the answer needs to be a file path rather than the name of a vendor.