Voltage Vet — Web Application Requirements
Draft v1 · August 2, 2026 · Prepared by Jake for review with Blake · Replaces voltagevet.com (Squarespace)
1. Purpose
Build one web application that replaces the Squarespace site and gives Blake a single internal tool for running Voltage Vet, a solo PEV repair business (e-scooters, EUCs, e-skateboards) in Brightwood, Washington, DC. Current volume is about five repair requests per week and growing; the weekly bookkeeping session is the main pain point.
The application must:
- Make triage fast. Many requests are for work Blake can't or won't do; declining should take seconds, and viable requests should move cleanly to a quote.
- Replace manual bookkeeping entry. Income and expenses (with receipt photos) are captured as they happen and pushed automatically to Blake's existing Google Sheets and Drive.
- Promote Apollo, Gotrax, Kingsong, and Voromotors with pages that serve both repair credibility and affiliate buying guides.
- Keep the drop-off address (Blake's home) private. It never appears publicly and is shared only after a quote is accepted.
- Cost less than the current site: total hosting under $300/year.
2. Current state
| Area | Today |
| Website | Squarespace (~$300/yr): marketing pages, estimate scheduling, about page, YouTube link. 250+ repairs across 60+ brands since 2022. |
| Intake and triage | Estimate requests; Blake follows up by text/call. Many requests are out of scope. |
| Phone | Google Voice business number (keeps customers out of personal contacts). |
| Quotes | Manual, over text. Tire jobs get two quotes — solid vs. air — with an explanation of trade-offs. |
| Drop-off | Blake's home; address shared privately after quote acceptance. |
| Waiver | Paper, signed at drop-off. No digital record. |
| Payments | Venmo, CashApp, cash; occasional Chime. Chase business account; card terminal wanted eventually. |
| Books | Google Sheets, entered manually weekly. Expense receipts uploaded to Drive and linked into the sheet by hand. |
| Pricing | Not published. Blake has a sheet of common services to publish as ranges. |
3. Decisions already made
From the August 2, 2026 interview.
- The app database (PostgreSQL) is the system of record for operations. Google Sheets remains the books, for accounting only — a deliberate slow transition.
- Squarespace is replaced entirely; the new site owns voltagevet.com. Hosting on Railway, under $300/yr total.
- Flow: request → triage conversation → quote (two options for tires) → address shared on acceptance → drop-off.
- Google Voice stays in v1. No telephony integration yet, but the data model must accommodate Twilio later without rework.
- Waivers: paper, with photo upload attached to the job. Digital signature deferred.
- Payments recorded manually in v1 (Venmo, CashApp, Chime, cash, Zelle). Future terminal through Chase, not Square.
- Status tracking is internal only; no customer-facing status page in v1.
- The app captures income per job and expenses with receipt photos, uploads receipts to Drive, and appends rows with Drive links to the existing Sheets.
- Common services are published as price ranges, with a solid-vs-air tire explainer.
- Admin access: Google sign-in, allow-list of two accounts (Blake and Jake).
4. Public website
Priority: Must = v1 launch. Should = v1 if time allows, else v1.1. Later = future phase.
| ID | Requirement | Priority |
| P-1 | Home page: services overview, trust facts (250+ repairs, 60+ brands, since 2022), brands, call to action to request a repair. | Must |
| P-2 | Services page publishing Blake's common services as price ranges, with a qualifier that final pricing depends on model, parts, and diagnosis. Ranges editable by Blake in the admin without a deploy. | Must |
| P-3 | Solid vs. air tire explainer (comfort, flats, weight, cost). This pre-answers the most common quote conversation. | Must |
| P-4 | Brand pages for Apollo, Gotrax, Kingsong, Voromotors: repair credibility plus buying guides with affiliate links (Kingsong link pending) and the required affiliate disclosure. | Must |
| P-5 | Repair request form: name, phone and/or email, preferred contact, device category/brand/model, service type, problem description, whether the device powers on, prior repairs or modifications. States that Blake will text to triage before quoting. | Must |
| P-6 | Location shown as "Brightwood, Washington, DC — near Takoma Park Metro; drop-off details shared after your quote is accepted." No street address anywhere: pages, structured data, or metadata. | Must |
| P-7 | Form spam protection: honeypot and rate limiting; add a CAPTCHA only if spam appears. | Must |
| P-8 | Redirects from existing Squarespace URLs. DNS migration must preserve MX/SPF/DKIM so [email protected] keeps working. | Must |
| P-9 | About page and YouTube channel link. | Should |
| P-10 | Closure banner (the shop closes annually, historically Jul 31–Aug 11), manageable from the admin. | Should |
| P-11 | Optional photo upload on the intake form. Helps triage but adds spam and file-handling surface; confirm value with Blake first. | Should |
| P-12 | Customer-facing quote acceptance and status links. | Later |
5. Repair workflow and internal admin
Statuses: Received → Triage (may loop through Awaiting Customer, or end at Not Serviceable) → Quote Draft → Quote Sent → Quote Accepted → Awaiting Drop-off (address may now be shared) → In Repair → Awaiting Pickup → Completed. Payment state (unpaid, partially paid, paid, refunded) is derived from payment records, not encoded in the status. Every transition is logged with actor and timestamp.
| ID | Requirement | Priority |
| W-1 | One repair-case record from intake through completion; it becomes a job when a quote option is accepted. No duplicate request/job records. | Must |
| W-2 | Triage inbox with new requests first and a one-click decline-with-reason (out of scope, parts unavailable, etc.). | Must |
| W-3 | Quotes are versioned and immutable once sent; corrections create a new version. A quote can carry multiple selectable options; tire quotes require both a solid and an air option. | Must |
| W-4 | Quote acceptance recorded manually (channel, who, when), since acceptance happens over Google Voice in v1. | Must |
| W-5 | The drop-off address is stored server-side only, revealed only on an accepted case to allow-listed admins, with every reveal logged. The reveal produces copy-paste text for Google Voice. | Must |
| W-6 | Email notification to Blake on new requests, containing a link only — no customer details in the email. | Must |
| W-7 | Customers and devices are first-class records (repeat customers, multiple devices, notes). | Must |
| W-8 | Saved reply and quote templates for common triage questions and the tire explanation. | Should |
| W-9 | Repair photos and internal checklists per job. | Later |
6. Communications
| ID | Requirement | Priority |
| C-1 | Per-customer, per-case communications log with fast manual entry (inbound/outbound call, text, email, in person, internal note). Blake keeps texting from Google Voice; the app holds the structured summary. | Must |
| C-2 | Twilio-ready schema: normalized phone numbers, direction, channel, provider and provider message ID, delivery status and event history, consent/opt-out history. A later Twilio integration writes to the same tables. | Must |
| C-3 | Twilio SMS integration (two-way texting in the app; requires A2P 10DLC business registration). | Later |
7. Waivers
| ID | Requirement | Priority |
| V-1 | Photo/scan upload of the signed paper waiver attached to the job: template version, signer name, signed date, original preserved unmodified. A replacement supersedes rather than overwrites. | Must |
| V-2 | Warn (or require an explicit override with reason) when marking a job In Repair without a waiver on file. | Should |
| V-3 | Digital signature flow. Legally viable under E-SIGN and DC UETA but requires consent capture, tamper-evident documents, customer copies, and attorney review. Possibly via an e-signature provider. | Later |
8. Payments
| ID | Requirement | Priority |
| M-1 | Manual payment recording per job: method (Venmo, CashApp, Chime, cash, Zelle, card terminal, other), amount, date, optional reference. Multiple payments, refunds, and adjustments per job. | Must |
| M-2 | Accepted payment methods listed on the public site. | Should |
| M-3 | Chase terminal: use a standalone Chase QuickAccept reader or Chase POS terminal and record its payments manually with the Chase transaction reference. Do not plan on a Chase API integration — Chase's small-merchant products do not realistically expose one (WePay targets software platforms, not individual merchants). Revisit only with written confirmation from Chase; monthly CSV reconciliation is the practical fallback. | Later |
| M-4 | Customer receipts emailed from the app, for any payment method. | Later |
| M-5 | Online card payment or pay-by-link. | Later |
9. Accounting and Google Sheets/Drive
Design principle: the app never loses a payment or expense because Google is unavailable. Records save to the app database first; a background queue pushes to Sheets and Drive with retries, and failures surface as a visible banner in the admin, not a log entry.
| ID | Requirement | Priority |
| A-1 | Income: each payment, refund, or adjustment appends one row to an app-owned tab (VV App Income) in Blake's existing workbook — date, job number, amount, method, memo, sync key. | Must |
| A-2 | Expenses: merchant, date, category, amount, payment method, and receipt photo. The app uploads the receipt to Blake's Drive folder and appends a row with the Drive link to VV App Expenses — replacing today's manual flow. | Must |
| A-3 | Writes are idempotent (stable sync keys, deterministic row allocation) so retries cannot create duplicate rows. Conflicts stop and alert rather than overwrite. | Must |
| A-4 | One-way sync only. Sheet edits never change app data; Blake can continue manual entries elsewhere in the workbook. | Must |
| A-5 | The Google connection is Blake's own OAuth grant with the narrow drive.file scope (only files he explicitly selects), token encrypted at rest, with a clear reconnect prompt if it expires. No customer contact information is exported to the workbook. | Must |
| A-6 | Sync health view: last successful sync, pending and failed rows, retry. | Must |
| A-7 | In-app ledger views and reports (monthly income, category totals), the eventual replacement for Sheets. | Later |
10. Non-functional requirements
- Budget. Total infrastructure under $300/yr. Expected roughly $9–14/month on Railway (app, PostgreSQL, scheduled sync job) with cost alerts at $12 and $15 and a hard cap at $18. Cloudflare R2 and Resend stay within free tiers at this volume.
- Maintainability. One repository, one deployable monolith. No Redis, queue service, CMS, or microservices — Jake maintains this alone.
- Privacy. The home address is a server-side secret with gated, logged reveal. Customer information never appears in logs, analytics, notification emails, or Sheets exports. No sequential IDs in URLs.
- Security. Google sign-in bound to stable Google account IDs, two-account allow-list, standard session and CSRF protections, rate limiting, private file storage with short-lived signed URLs, upload validation (images and PDF only, 15 MB cap, no video).
- Durability. Daily database backups on Railway plus weekly encrypted logical backups to R2. A restore is tested before launch. Waiver originals are immutable.
- Audit. Logins, status overrides, quote sends and acceptances, address reveals, waiver uploads, payment changes, and sync retries are all recorded.
11. Architecture summary
| Layer | Choice | Rationale |
| Application | Next.js (App Router), TypeScript; one deployable serving the public site and admin | Static, SEO-friendly marketing pages and a dynamic admin in one codebase |
| Database | PostgreSQL with Prisma; UUID keys; money stored as integer cents | Transactions for status changes and the sync queue; conventional tooling |
| Hosting | Railway: web service, PostgreSQL, and a scheduled sync runner (same image, runs every ~5 minutes, exits) | Fits the budget; a scheduled job beats an always-on worker at this volume |
| Files | Private Cloudflare R2 bucket for waivers and receipts; receipts mirrored to Blake's Drive | Effectively free at this volume; Drive remains an accounting convenience, not primary storage |
| Auth | Google sign-in (Auth.js), two-account allow-list; a separate OAuth grant from Blake, scoped to drive.file, for the books | Jake's login never receives Drive access; narrow scope avoids Google verification burden |
| Sync | Transactional outbox: the record and its sync task are saved atomically; idempotent Sheet and Drive writes with backoff | A Google outage cannot lose bookkeeping data or duplicate rows |
| Content | Marketing and brand pages as Markdown in the repository; service price ranges as database records editable in the admin | Prices change without deploys; prose stays version-controlled; no CMS |
| Email | Resend free tier, internal alerts only | New-request and sync-failure notifications |
12. Mockups
Interactive mockups (self-contained HTML): mockups.html. Screens: public home, services and pricing with the tire comparison, brands, repair request form; admin request queue, job detail (status timeline, communications log, two-option quote builder, waiver upload, payment entry), and accounting (income from paid jobs, expense capture, sync panel).
13. Phased roadmap
| Phase | Scope |
| 0 — Prep | Inventory Squarespace URLs and DNS (protect email), collect Blake's price sheet, inspect the accounting workbook and Drive folder, agree on sheet columns and categories, review the paper waiver, confirm Google accounts. |
| 1 — Launch | All Must items above: public site with redirects, intake, the full triage-to-completion workflow, communications log, waiver upload, manual payments, expense capture, Sheets/Drive sync, backups. |
| 1.1 — Polish | Templates, queue tuning from real use, customer email receipts, closure banner, Chase CSV reconciliation if needed. |
| 2 — Twilio | Two-way SMS in the app on a business number; Google Voice stays until proven. |
| 3 — Customer links | Expiring links for quote review/acceptance and receipts. |
| 4 — Digital waivers | After attorney review; possibly via an e-signature provider. |
| 5 — Payments | Chase terminal in use; automation only if Chase confirms real API access. |
| 6 — Affiliate growth | First-party redirect links with click counts (no customer data), per-program disclosures. |
14. Additional considerations
- Email must survive the migration. [email protected] depends on DNS records at the current registrar. The cutover must preserve MX/SPF/DKIM/DMARC or business email breaks silently.
- DC sales tax. Repair labor and parts may be taxed differently in DC. Whether published ranges and quotes are tax-inclusive shapes the sheet columns; ask Blake's accountant before building the sync.
- Legal and insurance. Whether the waiver actually protects a home-based business working on lithium-battery vehicles is a question for a DC attorney, as is insurance: coverage for customer devices stored at the house and fire risk from charging batteries.
- Local SEO without an address. Use service-area structured data (no street address), a Google Business Profile configured as a service-area business, and redirects from the old URLs.
- Reviews. Nothing currently captures social proof. Texting a Google review link at pickup costs nothing; a testimonials section is cheap.
- Intake policy. Publishing what Blake does not take (e.g., water-damaged packs, hoverboards) pre-filters exactly the triage load the app is meant to reduce.
- Turnaround and appointments. The site should state typical turnaround and that drop-off is by appointment, so nobody arrives unannounced at a private home.
- Retention and deletion. Decide how long waivers, receipts, and closed cases are kept, and what happens if a customer asks to be deleted (financial records stay; triage photos and messages need not).
- Affiliate program terms. Each program has its own link format, disclosure, and sometimes logo rules; collect these before finalizing the brand pages.
- The annual closure. The intake form should set expectations during the closure rather than going silent.
15. Open questions
Before building the Google sync
- Is Blake's Google account consumer Gmail or Workspace? Which workbook and Drive folder are the books?
- Is it acceptable to add two app-owned tabs (
VV App Income, VV App Expenses) to the existing workbook?
- Does Blake sort, insert, or delete rows in his sheets today?
- Exact columns and expense categories; how refunds and corrections should appear; tax treatment.
Before building the workflow
- Can Jake reveal the drop-off address, or only Blake?
- Is payment required before pickup, or are unpaid completions allowed with an override?
- When does an unanswered quote close? Can a device ever be dropped off without a signed waiver?
Before public launch
- Which services and ranges from Blake's sheet are approved for publication, and are they tax-inclusive?
- Which brand logos and images may legally be used? What disclosure does each affiliate program require?
- Are intake photos worth the spam surface in v1?
- Which Chase product is Blake considering (QuickAccept reader vs. Chase POS terminal), and is Chase's own receipt sufficient until the app sends receipts?
16. Out of scope for v1
- Twilio or any telephony integration (Google Voice continues)
- Customer accounts, status pages, or online quote acceptance
- Digital waiver signatures
- Online card payments, pay links, or processor API integrations
- Customer receipts from the app
- Affiliate click analytics beyond plain outbound links
- Double-entry accounting or a general ledger in the app
- Inventory or parts management
Sources: stakeholder interview (Aug 2, 2026), review of the current voltagevet.com, architecture proposal (adopted with edits), UI mockups at mockups.html.