Commit Graph
63 Commits
Author SHA1 Message Date
austin 23ffb8221c Merge the catalogue admin (your branch, reconciled onto main) 2026-07-23 13:10:46 -05:00
austin 91219efbaa Reconcile: your admin wins, keeping main's non-admin work
You built a self-service catalogue admin on feature/admin-and-ui-wins while I built a
competing one that had already merged and deployed. Both forked from 27821cd. Per your
call, your implementation is the one that stays.

Kept from main (files your branch didn't touch, so no conflict):
- the CI test gate (tests now run and block the image)
- motion 12.42.2
- the platform contract test

Took from your branch:
- split AdminProductController / AdminCategoryController + ProductPhotoService (server-side
  webp via cwebp)
- a real category table (Category, V3__categories.sql) behind the product filters
- pages/Admin.tsx, with server-side /admin protection that redirects a browser to Authentik
  and returns it to /admin afterward — cleaner than my client-side gate, and it avoids the
  post-login-to-home issue my version had

Deleted my competing admin (AdminController, MeController, pages/admin/*, auth.tsx, and my
admin tests).

Grafted onto your gallery: swipe + arrow keys, which the deployed version had and yours
didn't. Added an AdminSecurityTest for your endpoints (admin closed, shop public, contact
CSRF) — the admin was otherwise untested, and CI now gates on tests.

Verified against a running container: /admin redirects a browser to Authentik (a bare 401
only for */* fetches, which is correct). 25 tests green.
2026-07-23 13:10:46 -05:00
austin 8a489409fd Return to where you signed in from, and take motion 12.42.2
Post-login landed on the home page. Spring only remembers the pre-login location when it
BOUNCES you off a protected page, but every route here is public — the SPA sends you to the
identity provider itself — so nothing is saved and login defaults to '/'. AuthProvider now
stashes the current path in sessionStorage before the redirect and navigates back once /api/me
confirms the session. sessionStorage, not a query parameter: it survives the redirect chain,
stays in this tab, and cannot be pointed at another site. Sign-in is only ever triggered from
an /admin route, so that is exactly where the reader is returned.

Also merges the motion 12.42.2 bump, which had stayed open on its own PR.
2026-07-23 12:34:31 -05:00
austin b27c3aa286 Merge pull request 'Update dependency motion to v12.42.2' (#7) from renovate/motion-12.x into main 2026-07-23 12:33:29 -05:00
austin ca4c22aa24 Remove the temporary gate probe
Confirmed: the run failed at the Test step and the registry digest was unchanged, so a
failing test now stops the image being published.
2026-07-23 12:20:14 -05:00
austin 01e68638f9 TEMPORARY: prove a failing test blocks the image
Will be reverted in the next commit. Verifying the gate rather than assuming it — the last
assumption of this kind was wrong for months.
2026-07-23 12:18:54 -05:00
austin 2ff472c810 CI: match the workspace volume on GITHUB_WORKSPACE
act_runner mounts it at the full repo path (/workspace/Owner/repo), not at /workspace, so
the previous lookup found nothing and the step refused to run — correctly, but for the
wrong reason.
2026-07-23 12:16:08 -05:00
austin 27ebf38502 CI: print the job container's mounts while wiring up the test step 2026-07-23 12:14:46 -05:00
austin 73e4b7fbef CI: actually run the tests, and let them gate the image
The image build runs 'mvn -DskipTests', and the workflow was only build -> Trivy -> push, so
no app test has ever run in CI. Only Trivy gated a merge. ContactControllerTest had been
broken since platform 0.1.6 and nothing noticed; the platform contract tests added in 0.1.9
were not running either, which defeated their purpose.

They cannot run inside 'docker build' — Testcontainers needs a Docker daemon and a build has
none. Maven runs as a sibling container instead, mounting the workspace volume act_runner
gave this job (discovered from our own container rather than guessed) and sharing the host
network so published test ports are reachable as localhost.

Fails loudly if the volume cannot be found, rather than quietly skipping the tests, which
would recreate exactly the problem this fixes.
2026-07-23 12:14:06 -05:00
austin 89e0ce31bb Merge feature/admin-ui-wins
Admin for the menu and enquiries, gallery swipe/keyboard, and the N+1 fix on product photos.
2026-07-23 12:07:46 -05:00
austin d2c62f35ed Admin for the menu and enquiries, plus gallery fixes
Admin
- /api/admin: products CRUD, the enquiry inbox, and presigned photo upload straight to the
  bucket so images never pass through the app. Gated by platform.security.authenticated-paths
  = /api/admin/**, so any signed-in Authentik user is staff — the alternative is a role model
  a two-person bakery would never maintain.
- /api/me is deliberately PUBLIC. The SPA asks on every page load, and requiring a login
  would bounce every anonymous visitor to Authentik just to read the menu.
- /admin screens: product list with edit and remove, an editor with drag-free photo
  reordering and upload, and an enquiry inbox that flags anything the relay refused.

Gallery
- swipe on touch devices, which the react-awesome-slider it replaced had and this did not,
  plus arrow keys and position dots — with swipe there is otherwise nothing to say a card
  holds more than one photo. Vertical drags are ignored so page scrolling still works.
- @BatchSize on the photo collection: the products page loaded the whole catalogue and
  Hibernate issued a query per product for its images, forty-odd round trips for a page
  that needs two.

Three things the tests caught, none of which are obvious:
- Adding the storage starter broke every existing test. It activates on a default endpoint,
  so an S3 client is built even in tests and dies on blank keys.
- MockMvc's webAppContextSetup leaves the security filter chain OUT, so the first version of
  the security test passed 200s and proved the opposite of what it claimed. It needs
  .apply(springSecurity()).
- Turning on the security starter turns on CSRF — for the PUBLIC contact form too, which
  then 403s. The SPA now reads the XSRF-TOKEN cookie and sends X-XSRF-TOKEN, and there is a
  test asserting the form is rejected without it.
2026-07-23 11:58:21 -05:00
austin 5dc365ad51 Update dependency motion to v12.42.2 2026-07-23 14:53:14 +00:00
austin 27821cdb90 Inherit the platform contract tests, and extend the shared Renovate preset
PlatformWebContract asserts what this app must do because it is on the platform: an /api
path matching no controller 404s rather than returning the SPA, health is UP, the liveness
and readiness probes exist, and a client-side route forwards to the shell. That first one
shipped broken to six live sites and was found by typing a URL by hand; now it fails a
build instead.

renovate.json is three lines pointing at austin/renovate-config. The rules were copied per
repo, so they matched only by luck and a change was six edits.

Platform 0.1.9.
2026-07-23 09:46:53 -05:00
austin 4c5537e593 Point the motion imports at the renamed package
Renovate's replacement PR swapped framer-motion for its successor 'motion' in
package.json but left the imports, so the build could not resolve them. The React entry
point is motion/react.
2026-07-23 08:52:01 -05:00
austin f89fcb13fa Merge pull request 'Update dependency vite-plugin-svgr to v5' (#5) from renovate/vite-plugin-svgr-5.x into main 2026-07-23 08:50:57 -05:00
austin 0d7a203a26 Merge pull request 'Update dependency typescript to v7' (#4) from renovate/typescript-7.x into main 2026-07-23 08:50:56 -05:00
austin 7ce674c370 Merge pull request 'Replace dependency framer-motion with motion' (#1) from renovate/framer-motion-replacement into main 2026-07-23 08:50:54 -05:00
austin b8e38d56a1 tsconfig: drop baseUrl, which TypeScript 7 removed
TS7 errors with 'Option baseUrl has been removed'. The paths mapping already points at
./src/*, which resolves relative to this file without it, and TS 5.9 accepts the same
config — so this lands safely ahead of the TypeScript 7 bump.
2026-07-23 08:50:29 -05:00
austin 4a59d3f42c Merge pull request 'Update bennett platform to v0.1.7' (#2) from renovate/bennett-platform into main 2026-07-23 07:44:14 -05:00
austin ea55de39d4 Update dependency vite-plugin-svgr to v5 2026-07-23 12:44:13 +00:00
austin 7789d0d2f4 Update dependency typescript to v7 2026-07-23 12:44:13 +00:00
austin b443c8d861 Replace dependency framer-motion with motion 2026-07-23 12:44:11 +00:00
austin 33b3d064c7 Update bennett platform to v0.1.7 2026-07-23 12:44:11 +00:00
austin 5380f477ca Platform 0.1.6 (contact security) + fidelity fixes from the port review
- .container back in @layer components so Tailwind's px-4 still wins; unlayered it had
  quietly widened the gutter on every page
- shadow-sm -> shadow-xs: Tailwind v4 renamed the scale, so the ported markup was giving
  every white card a heavier shadow than the live site
- route changes jump to the top again instead of smooth-scrolling
- preload the wordmark font and the hero image
2026-07-23 06:09:38 -05:00
austin 292a8e3087 Platform 0.1.5: fail fast on a blank contact recipient 2026-07-22 22:18:23 -05:00
austin f471462d05 Rewrite on the Bennett platform: Spring Boot + Vite/React SPA
Replaces the Next.js app. Same site, same look; the parts that were decisions rather
than markup now live in Java.

- catalogue, curated order, category filter and image URLs move from a TypeScript array
  into Postgres behind /api/products and /api/categories
- contact form uses the shared platform-starter-contact: validate, RECORD, send, then
  fan out to n8n. Recording first means a relay outage costs a notification, not an enquiry
- PageMetaController rewrites title/description/OG per route, replacing what Next's SSR
  gave crawlers and link-preview scrapers
- 50MB of photos leave the repo for the MinIO bucket, re-encoded to webp (14MB) with EXIF
  (including phone GPS) stripped
- fixes a catalogue typo: 'Strawberry Pie' was category 'Pies', which no filter matched, so
  it was unreachable unless browsing All
2026-07-22 22:09:51 -05:00
austin 207415dbbe ci: exercise workflow_run webhook (no-op) 2026-07-22 19:50:15 -05:00
austin 7eefc5d008 contact: fan out enquiries to n8n hub (fire-and-forget)
Keeps the direct SMTP email as the reliable delivery path; when CONTACT_HUB_URL
is set, also POSTs the enquiry to the n8n webhook so the hub sends the customer
auto-reply and (later) creates CRM/task records. Best-effort with a 4s timeout,
so a slow or down hub never blocks or fails the form.
2026-07-22 18:12:45 -05:00
austin eb8cc01a59 contact route: optional SMTP auth + trust local self-signed relay/bridge 2026-07-22 15:17:06 -05:00
austin a142269a59 ci: push image under thevine org after repo move 2026-07-22 11:53:58 -05:00
austin ade2aec063 ci: re-trigger build after runner docker.sock fix 2026-07-22 10:50:09 -05:00
austin 91a37a8d06 Add Docker build + Gitea Actions CI for self-hosting
- next.config: output 'standalone' for a self-contained server bundle
- Dockerfile: multi-stage Next.js build (node:22-alpine)
- .gitea/workflows/deploy.yml: build + push to the Gitea registry
2026-07-22 10:44:04 -05:00
Austin d8ec865385 Enable Next image optimization now that hosting is Vercel
Firebase static export forced images.unoptimized; Vercel runs the optimizer,
so drop it to auto-resize and serve WebP for the product photos.
2026-07-14 17:51:20 -05:00
Austin 5c81b65e51 Rebrand to Sage & Cream identity, working contact form, drop Firebase
- New sage/cream palette and stacked logo lockup (The Vine over Coffeehouse
  + Bakery) driven by currentColor; logo SVGs now colorable
- Reuse the logo component for the hero and section marks
- Rewrite site copy: real founding (Morissa Bennett, 2024), real story from
  the product range, remove invented claims and AI phrasing
- Contact form now sends over SMTP via /api/contact (nodemailer) with real
  send/error states, server-side validation, and reply-to the customer;
  delivers to CONTACT_TO. Add .env.example and a test-email script
- Fix mobile: unmount the off-screen menu (killed sideways scroll), cap logo
  width, responsive heroes and type
- Remove Firebase (config, tracked build output, placeholder pages, nix
  firebase-tools) now that hosting has moved
- Delete dead code: LoyaltyCardForm, ProductModal, LoadingSpinner, card-flip
  CSS, unused Playfair font
- Serve dev/start on port 2024
2026-07-14 17:48:00 -05:00
Austin f4ce93965b updated hours 2026-03-14 11:32:25 -05:00
Austin 34a81ffc09 updated hours 2026-03-14 11:29:08 -05:00
Austin 2ac068f264 updated dependencies 2026-02-02 18:14:24 -06:00
austin fae1be2b39 added a dynamic favicon 2025-02-25 16:54:58 -08:00
austin 4e4c7a68f3 removed unessesary images 2025-02-25 16:54:45 -08:00
Austin Bennett 5cbf3dde89 idk browski 2025-02-24 13:54:43 -06:00
Austin Bennett 504642df8d fixed hours & location 2025-02-21 18:27:37 -06:00
Austin Bennett 6caad2e94b idk 2025-02-21 15:11:57 -06:00
Austin Bennett 150e85b3a3 fixed categories 2025-02-21 15:10:13 -06:00
Austin Bennett 3deb8a4aec disabled contact page & fixed images 2025-02-21 15:07:16 -06:00
Austin Bennett d27c355198 fixed eslint issues 2025-02-21 14:51:41 -06:00
austin df5cc5f022 removed history page 2025-02-11 10:45:19 -06:00
austin dcda124b31 updated readme 2025-02-10 12:45:41 -06:00
austin c9eb6480da updated default.nix shell for nextjs 2025-02-10 12:42:19 -06:00
austin 769e99d4c3 2.0 2025-02-08 14:24:51 -06:00
Paul Fresnel d643be301f redirect fix 2024-11-09 17:40:08 +01:00