| phase |
plan |
subsystem |
tags |
requires |
provides |
affects |
tech-stack |
key-files |
key-decisions |
requirements-completed |
duration |
completed |
| quick-260718-9qg |
01 |
docs |
| quickbooks |
| qbo |
| oauth2 |
| integration |
| handoff |
| finance |
|
|
| QBO_INTEGRATION_HANDOFF.md — self-contained OAuth2/token/API/gotchas reference for QuickBooks Online, written for a team with no access to Pulse's codebase |
|
| any future work building or maintaining a QBO integration in a different app |
|
|
| created |
modified |
| QBO_INTEGRATION_HANDOFF.md |
|
|
|
| Inlined every detail (env vars, exact Intuit URLs, table schemas, request/response shapes) rather than pointing at Pulse source files, per the plan's self-containment requirement |
| Called out two real defects found during investigation as explicit gotchas rather than silently working around them: unverified OAuth `state` (CSRF gap) and the legacy `NEXTAUTH_URL` env var used for the redirect URI instead of Pulse's actual BETTER_AUTH_URL |
| Used placeholder values for all env var examples — no real secrets existed in .env for QBO_* keys to begin with, so nothing needed redaction |
|
|
25min |
2026-07-18 |
Phase quick-260718-9qg Plan 01: QBO Integration Handoff Doc Summary
Self-contained QBO_INTEGRATION_HANDOFF.md covering QBO's OAuth2 authorization-code flow, token storage/refresh schema, sandbox vs production API base URLs, minor-version pinning, and 11 concrete gotchas (deletion-diffing, CSRF state, report NoReportData markers, check-number normalization, idempotency, etc.) drawn from Pulse's actual QBO source and its recent AR-reconciliation fix.
Performance
- Duration: ~25 min
- Started: 2026-07-18T11:00:00Z (approx.)
- Completed: 2026-07-18T11:25:00Z (approx.)
- Tasks: 1
- Files modified: 1 (new file)
Accomplishments
- Investigated Pulse's real QBO integration end to end:
lib/services/qbo-client.ts, lib/services/qbo-sync-service.ts, all four app/api/qbo/* routes, migrations/051_create_qbo_tables.sql, migrations/088_qbo_invoices_soft_delete.sql, middleware.ts public-route list, integration-health.ts config check, git history (b98c674, ef9b31e, 672f17b), and the 260519-0oz quick-task SUMMARY for the createPayment/createDeposit work.
- Wrote
QBO_INTEGRATION_HANDOFF.md (596 lines) at the repo root with all required sections: Overview, Prerequisites, Environment variables (table), OAuth2 connection flow (11-step numbered walkthrough with exact Intuit URLs), Token storage & refresh (generalized schema + pseudocode), API usage (base URLs, path shape, minorversion, query/write/report examples), Gotchas & lessons learned (11 concrete items), and a framework-agnostic TypeScript pseudocode code-flow example.
- Surfaced two real defects discovered during investigation as explicit gotchas for the new team to avoid repeating: (1) Pulse's OAuth
state value is generated but never persisted/verified on callback — a real CSRF gap; (2) the redirect-URI base URL is read from NEXTAUTH_URL, a variable not present anywhere in Pulse's .env/.env.local (a legacy holdover from a prior auth library), distinct from the app's actual BETTER_AUTH_URL.
Task Commits
Each task was committed atomically:
- Task 1: Investigate Pulse's QBO integration and write the self-contained handoff doc -
ea8a36b (docs)
Plan metadata: (this commit, made after SUMMARY.md)
Files Created/Modified
QBO_INTEGRATION_HANDOFF.md - Self-contained QBO integration handoff document (overview, prerequisites, env vars, OAuth2 flow, token storage/refresh, API usage, gotchas, code-flow example)
Decisions Made
- Inlined every Pulse-derived detail directly into the doc (no bare
see lib/services/qbo-client.ts pointers); Pulse file paths appear only as parenthetical provenance notes.
- Documented the
NEXTAUTH_URL / BETTER_AUTH_URL mismatch and the unverified OAuth state as explicit "don't repeat this" gotchas rather than omitting them, since the plan's objective is transferring hard-won (including negative) knowledge to a new team.
- Recommended
crypto.randomUUID() (or a signed token) plus server-side verification in place of Pulse's current Math.random()-based state, and recommended adding an explicit Intuit token-revocation call for a real "disconnect," since a new implementation should start from a stronger baseline than Pulse's current code.
Deviations from Plan
None - plan executed exactly as written. This was a docs-only investigation-and-write task; no application source, migrations, env files, or existing docs were touched (confirmed via git status --short, which shows only QBO_INTEGRATION_HANDOFF.md as an addition).
Issues Encountered
None.
User Setup Required
None - no external service configuration required. This task only produced a reference document; it does not change any running behavior.
Next Phase Readiness
QBO_INTEGRATION_HANDOFF.md is ready to be handed directly to the new application's engineering team.
- No blockers. If the new team later reports gaps (e.g. QBO Payments/charge-card scope, multi-realm support), a follow-up quick task can extend this document — it was intentionally scoped to what Pulse's own integration actually covers (accounting scope only, single realm).
Self-Check: PASSED
QBO_INTEGRATION_HANDOFF.md exists at repo root — FOUND
- Automated verify command (
test -f ... && line count >= 100 && grep oauth/refresh/sandbox|production) — PASSED (OK)
- Commit
ea8a36b exists in git log — FOUND
git status --short shows only QBO_INTEGRATION_HANDOFF.md as a tracked addition (plus the pre-existing untracked .planning/quick/260718-9qg-.../ plan directory, unrelated to source/docs/migrations) — CONFIRMED
Phase: quick-260718-9qg
Completed: 2026-07-18