This repository has been archived on 2026-09-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
itsthevine/pom.xml
T
austin 5045ccc7c8 The admin is Thymeleaf too: no JavaScript framework left in the repo
The last React went with this. /admin and /admin/catering are pages of forms; every write is a POST and
a redirect back, so the back button and reload do what they look like they do, a double-tap cannot
repeat an upload, and there is no client-side state to lose — a reload is always the truth. The
/api/admin/** endpoints went too: they existed for the React screen, and their logic now lives in
Catalogue (extracted from the two deleted JSON controllers) and CateringMenu, which the pages call.

THE TABLE EDITOR IS THE INTERESTING PART, because a catering table cannot be edited a field at a time
— a column heading, its price and the entries beneath it only mean anything together. One form holds
the whole table and every button submits it; `name="do"` says which was pressed and its value carries
the position (`remove-column:2`). "Add a column" therefore arrives with every cell the editor has
typed, adds the column to what arrived plus an empty entry on every line, and re-renders. Nothing
typed is lost, and only Save writes — so a half-built table with a blank heading never reaches the
live page. A failed save comes back the same way, with the work still in the form and the reason above
it; a redirect would throw the work away and leave them guessing which cell the message was about.
Spring binds `lines[2].values[1]` into the right cell, which flat repeated parameters could not
promise.

Reordering moved to the server, where it always belonged: the browser used to compute the new order
and send the whole list back, and now "move this up" arrives as an action. Same for arranging photos —
one endpoint takes the key and -1/1/0 (earlier, later, remove), because those three buttons are the
same edit.

frontend/ became styles/: node, Tailwind and nothing else. It exists because Tailwind needs a
compiler and the alternative is a hand-written stylesheet; there is no bundler and no framework. The
admin's controls are @utility classes (v4 will only let you @apply a registered utility, and only a
utility can take the `file:` variant the photo pickers use) — the same buttons the React screen had,
from the same class strings it composed. Also fixed .gitignore, which still named frontend/: with
styles/ unlisted, `git add -A` staged 1,626 files of node_modules.

Verified against a running container, not only in tests: pressing "+ Column" returns the draft with an
unsaved cell intact, a new column and a matching new entry on the line, "Not saved yet" — and the live
page unchanged; Save then writes both columns with the price parsed from "48". Renaming and moving an
item land on the products page. Deleting a category that is in use is refused with the sentence naming
it. Removing the only photo of an item is refused, and that button is already disabled in the page.

51 tests (10 new): the form binding, the flash on success and on refusal, a structural button writing
nothing, and the whole admin surface closed to anonymous visitors. PlatformContractTest's routing
assertion now says what is true — an unknown path 404s, and so does /admin when no identity provider
is configured, because AdminController only exists under OIDC.
2026-07-26 16:47:10 -05:00

178 lines
7.7 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-parent</artifactId>
<version>0.1.9</version>
<relativePath/>
</parent>
<groupId>com.itsthevine</groupId>
<artifactId>itsthevine</artifactId>
<version>0.1.0</version>
<name>The Vine Coffeehouse + Bakery</name>
<description>Site for The Vine in Princeville, IL — menu, story, and contact form — on the Bennett platform.</description>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>0.1.9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Boot 4.1 no longer manages the raw org.testcontainers:* module versions -->
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-bom</artifactId>
<version>1.21.4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Platform releases live in the Gitea Maven registry (anonymous read). Declared here so Renovate
can discover new platform versions and open a bump PR. Maven still needs this repo in
settings.xml for PARENT resolution (see .gitea/ci-settings.xml). -->
<repositories>
<repository>
<id>gitea</id>
<url>https://git.thebennett.net/api/packages/austin/maven</url>
<releases><enabled>true</enabled></releases>
<snapshots><enabled>false</enabled></snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-starter-web</artifactId>
</dependency>
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-starter-data</artifactId>
</dependency>
<!-- The site is server-rendered: every public page is a Thymeleaf template in
src/main/resources/templates, and the only JavaScript left on it is a 100-line file that
gives the multi-photo product cards their arrows. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-starter-contact</artifactId>
</dependency>
<!-- The site is still a public brochure, but the catalogue is now editable from it: the admin
screens sign in against Authentik (OIDC) and upload photos to the bucket. Both are off
unless platform.security.mode=OIDC, which is what gates the admin endpoints existing at
all — see AdminProductController. -->
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-starter-security</artifactId>
</dependency>
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-starter-storage</artifactId>
</dependency>
<!-- test -->
<!-- Contract tests every app on the platform inherits. -->
<dependency>
<groupId>net.thebennett.platform</groupId>
<artifactId>platform-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- springSecurity() for MockMvc — without it the filter chain is absent and every protected
path answers 200, so a security test would prove the opposite of what it claims. -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!--
There is no JavaScript application here any more, so node is present for one reason:
Tailwind needs a compiler, and the alternative to it is a hand-written stylesheet.
`styles/` is the whole asset pipeline (see styles/site.css).
-->
<plugin>
<groupId>com.github.eirslett</groupId>
<artifactId>frontend-maven-plugin</artifactId>
<configuration>
<!-- Overrides platform-parent's `frontend`, which was where the SPA lived. -->
<workingDirectory>styles</workingDirectory>
</configuration>
<executions>
<!--
Tailwind, over every template, straight into the build output.
process-classes, not prepare-package: `mvn spring-boot:run` stops at
process-classes, and bound any later a local run would serve an unstyled site. The
output goes to target/classes/static/css so the generated file can never be
mistaken for a source file.
-->
<execution>
<id>npm-build-css</id>
<phase>process-classes</phase>
<goals><goal>npm</goal></goals>
<configuration><arguments>run build:css</arguments></configuration>
</execution>
<!-- Inherited from platform-parent to build an SPA at prepare-package. There isn't
one; the stylesheet is already built above. -->
<execution>
<id>npm-build</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<!-- Same: this copied frontend/dist into the jar's static/. No dist, nothing to
copy — the pages are templates and the stylesheet is written straight to
target/classes/static/css. -->
<execution>
<id>copy-frontend</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>