Compare commits

..

2 Commits

23 changed files with 68 additions and 14 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@
docs/sca-psd2-compliance.md
accept-a-payment/
codemap/
FULFILLMENT.md

3
api/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Command api is the HTTP backend: it boots the router, bolts on all the
// middleware, and answers the requests the TUI throws at it.
package main

3
api/handlers/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package handlers is where the real work happens, one function per endpoint:
// carts, orders, products, addresses, cards, webhooks, and the rest.
package handlers

4
api/middleware/doc.go Normal file
View File

@@ -0,0 +1,4 @@
// Package middleware holds the stuff that runs on every request before a
// handler ever sees it: auth, CORS, logging, rate limiting, metrics, and a
// recovery net for panics.
package middleware

3
api/routes/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package routes is the switchboard: it maps every URL to the handler that
// knows what to do with it.
package routes

View File

@@ -0,0 +1,3 @@
// Command reconcile-cards hunts down saved cards that Stripe no longer knows
// about and detaches them. Run it with -dry-run first if you're nervous.
package main

3
pkg/api/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package api is the client side of the house: it talks to our HTTP backend
// so other Go code doesn't have to hand-roll requests.
package api

3
pkg/auth/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package auth sorts out who you are: logging in with an SSH key and minting
// the JWT you carry around afterwards.
package auth

3
pkg/bring/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package bring talks to Bring, the Norwegian postal service, for booking
// shipments and printing labels.
package bring

3
pkg/config/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package config reads everything out of the environment so secrets and
// settings stay out of the source code.
package config

3
pkg/database/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package database opens the SQLite connection, runs the migrations, and
// drops in some seed data so the shop isn't empty on a fresh boot.
package database

3
pkg/models/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package models is the shared vocabulary of the app: coffee, carts, orders,
// addresses, cards, users, and the other nouns everything passes around.
package models

3
pkg/observability/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package observability sets up tracing and structured logs so that when
// something breaks at 3am you stand a chance of figuring out why.
package observability

3
pkg/shipping/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package shipping holds the plain shipping types that the rest of the app
// passes back and forth.
package shipping

2
pkg/shippo/doc.go Normal file
View File

@@ -0,0 +1,2 @@
// Package shippo talks to the Shippo API for shipping rates and labels.
package shippo

3
pkg/stripeclient/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package stripeclient wires up the Stripe SDK once at startup (with tracing
// baked in) so everyone else can just make calls.
package stripeclient

3
pkg/tui/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package tui is the terminal UI you see over SSH: the shop, the cart, your
// account, and the checkout flow, all drawn with Bubbletea.
package tui

View File

@@ -276,9 +276,7 @@ func (m Model) updatePaymentViewport() Model {
breadH := lipgloss.Height(m.BuildBreadcrumbs())
footerH := lipgloss.Height(m.BuildFooter())
availH := m.heightContainer - headerH - footerH - breadH
if availH < 1 {
availH = 1
}
availH = max(availH, 1)
if !m.payment.viewportReady {
m.payment.viewport = viewport.New(viewport.WithWidth(m.widthContent), viewport.WithHeight(availH))
m.payment.viewport.KeyMap = viewport.KeyMap{}
@@ -303,7 +301,7 @@ func (m Model) PaymentPageView() string {
m.widthContainer,
m.payment.viewport.Height(),
lipgloss.Center, lipgloss.Center,
m.renderPaymentHttpsView(),
m.renderPaymentHTTPSView(),
)
} else if m.payment.view == 0 && m.payment.form == nil {
content = m.RenderCardList()
@@ -374,7 +372,7 @@ func (m Model) RenderCardList() string {
return lipgloss.JoinVertical(lipgloss.Left, parts...)
}
func (m Model) renderPaymentHttpsView() string {
func (m Model) renderPaymentHTTPSView() string {
baseStyle := m.theme.TextLabel()
accentStyle := m.theme.TextHighlight()

3
pkg/tui/qrfefe/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package qrfefe turns text into a QR code drawn with terminal block
// characters, handy for showing links you can scan right off the screen.
package qrfefe

View File

@@ -24,9 +24,7 @@ const (
// menu(menuW+4) + gap(1) + detail(detailW+4) = contentW = wideW + 4.
func (m Model) shopLayout() (contentW, menuW, detailW, wideW int) {
contentW = m.widthContent
if contentW > 74 {
contentW = 74
}
contentW = min(contentW, 74)
wideW = contentW - 4
if m.size < large {
// Stacked layout: both panels span the full content width.
@@ -66,6 +64,7 @@ func clampLines(s string, n int) string {
// roastMeter renders the strength dots, e.g. ● ● ● ○ ○
func roastMeter(n int) string {
n = max(0, min(n, 5))
on := lipgloss.NewStyle().Foreground(cGold).Render(strings.Repeat("● ", n))
off := pDim.Render(strings.Repeat("○ ", 5-n))
return strings.TrimRight(on+off, " ")
@@ -218,12 +217,8 @@ func (m Model) shopMoveSelected(previous bool) Model {
} else {
next++
}
if next < 0 {
next = 0
}
if next >= len(m.Coffees) {
next = len(m.Coffees) - 1
}
next = max(next, 0)
next = min(next, len(m.Coffees)-1)
m.shop.selected = next
return m
}

3
pkg/tui/theme/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package theme keeps the colors and styles in one spot so the whole UI
// looks like it was built by the same person.
package theme

3
pkg/utils/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package utils is the catch-all drawer for tiny HTTP helpers that didn't
// earn a package of their own.
package utils

3
pkg/validate/doc.go Normal file
View File

@@ -0,0 +1,3 @@
// Package validate gives user input a once-over before the rest of the app
// trusts it.
package validate