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:

2. Current state

AreaToday
WebsiteSquarespace (~$300/yr): marketing pages, estimate scheduling, about page, YouTube link. 250+ repairs across 60+ brands since 2022.
Intake and triageEstimate requests; Blake follows up by text/call. Many requests are out of scope.
PhoneGoogle Voice business number (keeps customers out of personal contacts).
QuotesManual, over text. Tire jobs get two quotes — solid vs. air — with an explanation of trade-offs.
Drop-offBlake's home; address shared privately after quote acceptance.
WaiverPaper, signed at drop-off. No digital record.
PaymentsVenmo, CashApp, cash; occasional Chime. Chase business account; card terminal wanted eventually.
BooksGoogle Sheets, entered manually weekly. Expense receipts uploaded to Drive and linked into the sheet by hand.
PricingNot published. Blake has a sheet of common services to publish as ranges.

3. Decisions already made

From the August 2, 2026 interview.

4. Public website

Priority: Must = v1 launch. Should = v1 if time allows, else v1.1. Later = future phase.

IDRequirementPriority
P-1Home page: services overview, trust facts (250+ repairs, 60+ brands, since 2022), brands, call to action to request a repair.Must
P-2Services 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-3Solid vs. air tire explainer (comfort, flats, weight, cost). This pre-answers the most common quote conversation.Must
P-4Brand pages for Apollo, Gotrax, Kingsong, Voromotors: repair credibility plus buying guides with affiliate links (Kingsong link pending) and the required affiliate disclosure.Must
P-5Repair 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-6Location 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-7Form spam protection: honeypot and rate limiting; add a CAPTCHA only if spam appears.Must
P-8Redirects from existing Squarespace URLs. DNS migration must preserve MX/SPF/DKIM so [email protected] keeps working.Must
P-9About page and YouTube channel link.Should
P-10Closure banner (the shop closes annually, historically Jul 31–Aug 11), manageable from the admin.Should
P-11Optional photo upload on the intake form. Helps triage but adds spam and file-handling surface; confirm value with Blake first.Should
P-12Customer-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.

IDRequirementPriority
W-1One repair-case record from intake through completion; it becomes a job when a quote option is accepted. No duplicate request/job records.Must
W-2Triage inbox with new requests first and a one-click decline-with-reason (out of scope, parts unavailable, etc.).Must
W-3Quotes 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-4Quote acceptance recorded manually (channel, who, when), since acceptance happens over Google Voice in v1.Must
W-5The 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-6Email notification to Blake on new requests, containing a link only — no customer details in the email.Must
W-7Customers and devices are first-class records (repeat customers, multiple devices, notes).Must
W-8Saved reply and quote templates for common triage questions and the tire explanation.Should
W-9Repair photos and internal checklists per job.Later

6. Communications

IDRequirementPriority
C-1Per-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-2Twilio-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-3Twilio SMS integration (two-way texting in the app; requires A2P 10DLC business registration).Later

7. Waivers

IDRequirementPriority
V-1Photo/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-2Warn (or require an explicit override with reason) when marking a job In Repair without a waiver on file.Should
V-3Digital 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

IDRequirementPriority
M-1Manual 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-2Accepted payment methods listed on the public site.Should
M-3Chase 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-4Customer receipts emailed from the app, for any payment method.Later
M-5Online 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.

IDRequirementPriority
A-1Income: 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-2Expenses: 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-3Writes are idempotent (stable sync keys, deterministic row allocation) so retries cannot create duplicate rows. Conflicts stop and alert rather than overwrite.Must
A-4One-way sync only. Sheet edits never change app data; Blake can continue manual entries elsewhere in the workbook.Must
A-5The 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-6Sync health view: last successful sync, pending and failed rows, retry.Must
A-7In-app ledger views and reports (monthly income, category totals), the eventual replacement for Sheets.Later

10. Non-functional requirements

11. Architecture summary

LayerChoiceRationale
ApplicationNext.js (App Router), TypeScript; one deployable serving the public site and adminStatic, SEO-friendly marketing pages and a dynamic admin in one codebase
DatabasePostgreSQL with Prisma; UUID keys; money stored as integer centsTransactions for status changes and the sync queue; conventional tooling
HostingRailway: 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
FilesPrivate Cloudflare R2 bucket for waivers and receipts; receipts mirrored to Blake's DriveEffectively free at this volume; Drive remains an accounting convenience, not primary storage
AuthGoogle sign-in (Auth.js), two-account allow-list; a separate OAuth grant from Blake, scoped to drive.file, for the booksJake's login never receives Drive access; narrow scope avoids Google verification burden
SyncTransactional outbox: the record and its sync task are saved atomically; idempotent Sheet and Drive writes with backoffA Google outage cannot lose bookkeeping data or duplicate rows
ContentMarketing and brand pages as Markdown in the repository; service price ranges as database records editable in the adminPrices change without deploys; prose stays version-controlled; no CMS
EmailResend free tier, internal alerts onlyNew-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

PhaseScope
0 — PrepInventory 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 — LaunchAll 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 — PolishTemplates, queue tuning from real use, customer email receipts, closure banner, Chase CSV reconciliation if needed.
2 — TwilioTwo-way SMS in the app on a business number; Google Voice stays until proven.
3 — Customer linksExpiring links for quote review/acceptance and receipts.
4 — Digital waiversAfter attorney review; possibly via an e-signature provider.
5 — PaymentsChase terminal in use; automation only if Chase confirms real API access.
6 — Affiliate growthFirst-party redirect links with click counts (no customer data), per-program disclosures.

14. Additional considerations

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Reviews. Nothing currently captures social proof. Texting a Google review link at pickup costs nothing; a testimonials section is cheap.
  6. 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.
  7. Turnaround and appointments. The site should state typical turnaround and that drop-off is by appointment, so nobody arrives unannounced at a private home.
  8. 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).
  9. Affiliate program terms. Each program has its own link format, disclosure, and sometimes logo rules; collect these before finalizing the brand pages.
  10. The annual closure. The intake form should set expectations during the closure rather than going silent.

15. Open questions

Before building the Google sync

  1. Is Blake's Google account consumer Gmail or Workspace? Which workbook and Drive folder are the books?
  2. Is it acceptable to add two app-owned tabs (VV App Income, VV App Expenses) to the existing workbook?
  3. Does Blake sort, insert, or delete rows in his sheets today?
  4. Exact columns and expense categories; how refunds and corrections should appear; tax treatment.

Before building the workflow

  1. Can Jake reveal the drop-off address, or only Blake?
  2. Is payment required before pickup, or are unpaid completions allowed with an override?
  3. When does an unanswered quote close? Can a device ever be dropped off without a signed waiver?

Before public launch

  1. Which services and ranges from Blake's sheet are approved for publication, and are they tax-inclusive?
  2. Which brand logos and images may legally be used? What disclosure does each affiliate program require?
  3. Are intake photos worth the spam surface in v1?
  4. 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

Sources: stakeholder interview (Aug 2, 2026), review of the current voltagevet.com, architecture proposal (adopted with edits), UI mockups at mockups.html.