From 89ab487431d66edfe765895d40e1ea3fad67f10f Mon Sep 17 00:00:00 2001 From: Jun-te Kim Date: Tue, 30 Dec 2025 15:45:20 +0000 Subject: [PATCH] added migration script --- ...1230154354_add_used_at_to_login_tokens.sql | 10 + db/atlas/stripe_invoice/migrations/atlas.sum | 3 +- stripe_to_invoice/app/login/page.tsx | 0 stripe_to_invoice/app/page.tsx | 249 +++--------------- 4 files changed, 42 insertions(+), 220 deletions(-) create mode 100644 db/atlas/stripe_invoice/migrations/20251230154354_add_used_at_to_login_tokens.sql create mode 100644 stripe_to_invoice/app/login/page.tsx diff --git a/db/atlas/stripe_invoice/migrations/20251230154354_add_used_at_to_login_tokens.sql b/db/atlas/stripe_invoice/migrations/20251230154354_add_used_at_to_login_tokens.sql new file mode 100644 index 0000000..7584ce4 --- /dev/null +++ b/db/atlas/stripe_invoice/migrations/20251230154354_add_used_at_to_login_tokens.sql @@ -0,0 +1,10 @@ +-- 0005_harden_login_tokens.sql + +ALTER TABLE login_tokens + RENAME COLUMN token TO token_hash; + +ALTER TABLE login_tokens + ADD COLUMN used_at TIMESTAMPTZ; + +-- optional but recommended +CREATE INDEX ON login_tokens (token_hash); \ No newline at end of file diff --git a/db/atlas/stripe_invoice/migrations/atlas.sum b/db/atlas/stripe_invoice/migrations/atlas.sum index 227351f..93adc57 100644 --- a/db/atlas/stripe_invoice/migrations/atlas.sum +++ b/db/atlas/stripe_invoice/migrations/atlas.sum @@ -1,6 +1,7 @@ -h1:dTHZRXvfJ8E0dSqq2PAuMLfFFRSDvt3OzgJKEGeXz2g= +h1:C2cfl5WnZmikvrVEqNmhQJhGCoVllvcs4vsgA1oN410= 0001_init.sql h1:gzb02ZbjrrJkXOC+2qIZsngnj7A+29O2/b4awScPlPs= 0002_auth.sql h1:4NhBu26dIBMy9gxMxM3tf6Z2CS2kfKlGjFBj07T/aBw= 0003_stripe_xero.sql h1:E2bcdUDnondsXwbdIwVlZqR4DQwzcoDiyeRFJwVxXwg= 0004_login_tokens.sql h1:rj1KcWu/0znh2YvtI7JV8Z2nwtL5rZzONbPwX1P+/PI= 20251228182659_add_used_at_to_login_tokens.sql h1:/0puYQvwBFzpfSKjiZj2XR/7Mui39lS/IbFZW1TPQOc= +20251230154354_add_used_at_to_login_tokens.sql h1:7CRBsyxNBk5Ffxx8wvmEy314yHgQ0QUgyB0GhxPMO6o= diff --git a/stripe_to_invoice/app/login/page.tsx b/stripe_to_invoice/app/login/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/stripe_to_invoice/app/page.tsx b/stripe_to_invoice/app/page.tsx index d68bb80..0d1db2d 100644 --- a/stripe_to_invoice/app/page.tsx +++ b/stripe_to_invoice/app/page.tsx @@ -1,251 +1,62 @@ // app/page.tsx -// This page doubles as: -// 1. A landing page -// 2. A product spec -// 3. A reminder to future-me what the hell I was building // -// If you’re reading this months later: hi 👋 -// The product is the automation, not the UI. +// CORE MVP PAGE +// Purpose: +// 1. Explain the automation +// 2. Point the user to the next action +// +// Everything else lives elsewhere. export default function Home() { return ( -
+
{/* -------------------------------------------------- - Intro + What this is -------------------------------------------------- */}

Stripe → Xero automation

-

- Automatically create and mark Xero invoices as paid when a Stripe payment succeeds. -
- Built for people who value time more than pressing buttons. +

+ When a Stripe payment succeeds, a Xero invoice is + automatically created and marked as paid.

{/* -------------------------------------------------- - High-level flow (human readable) + What the user does -------------------------------------------------- */}
-

How it works (high level)

+

+ How it works +

-
    -
  1. Log in via magic link (passwordless)
  2. -
  3. Connect your Stripe account
  4. -
  5. Connect your Xero organisation
  6. -
  7. A Stripe payment succeeds
  8. -
  9. An invoice appears in Xero as paid
  10. +
      +
    1. Log in with your email
    2. +
    3. Connect Stripe
    4. +
    5. Connect Xero
    6. +
    7. Invoices handle themselves. You focus on the business.
{/* -------------------------------------------------- - Magic link auth – detailed flow + Next action -------------------------------------------------- */} -
-

Login flow (magic link)

- -

- Authentication is passwordless. We only store intent and proof of login. +

+

+ Start by logging in.

- {/* Text-based flow diagram (easy to read + copy) */} -
-{`Browser
-  |
-  | POST /auth/login (email)
-  v
-Backend
-  - find or create user
-  - generate token
-  - hash token
-  - store login_tokens row
-  - send email (SES)
-  |
-  v
-Email (magic link)
-  |
-  | GET /auth/callback?token=XYZ
-  v
-Backend
-  - hash token
-  - validate token (unused + not expired)
-  - mark token as used
-  - create session
-  |
-  v
-Set session cookie
-`}
-        
- - {/* Step-by-step breakdown */} -
    -
  1. - User enters their email address. -
  2. - -
  3. - Backend creates (or finds) a user record and stores a one-time login token - in login_tokens. -
  4. - -
  5. - An email is sent containing a short-lived magic link. -
  6. - -
  7. - When the link is clicked, the token is validated, marked as used, - and a session is created. -
  8. - -
  9. - A secure session cookie is set. No passwords. No OAuth popups. -
  10. -
+ + Log in → +
- {/* -------------------------------------------------- - Stripe → Xero automation flow - -------------------------------------------------- */} -
-

Stripe → Xero automation flow

- -
-{`Stripe payment succeeds
-  |
-  | Webhook
-  v
-Backend
-  - verify Stripe event
-  - map payment to customer
-  - create Xero invoice
-  - mark invoice as paid
-  |
-  v
-Xero (reconciled automatically)
-`}
-        
- -

- Once connected, everything runs automatically. - No manual reconciliation. No “awaiting payment” state. -

-
- - {/* -------------------------------------------------- - Proof - -------------------------------------------------- */} -
-

Proof, not promises

- -

- Your next Stripe payment will automatically reconcile in Xero. -
- No manual matching. No bookkeeping busywork. -

-
- - {/* -------------------------------------------------- - Pricing - -------------------------------------------------- */} -
-

Pricing

- -

- £200 / month — unlimited invoices. -

-
- - {/* -------------------------------------------------- - Footer / reminder - -------------------------------------------------- */} -
-

- This page is intentionally simple. -
- The product is the automation, not the UI. -

-
- - -
-

Implementation notes (for future me)

- -

- These are the only docs needed to implement magic-link auth with Next.js + AWS SES. -

- - -
-
) }