Architecture
Architecture
Purpose: describe the current stable technical map of the system.
Instructions:
- Document the system as it currently exists in stable form.
- Focus on major components, boundaries, interfaces, data flow, storage, external dependencies, and invariants.
- Update this file when implemented changes alter the stable technical shape of the system.
- Keep this file descriptive of current reality, not speculative.
- Do not use this file as a task log, scratchpad, or decision diary.
- Additional documents may be created when describing the details of major components. For example, the documentation for an API may be linked to an OpenAPI specification at
docs/api.yaml.
System Overview
Hermeticus is a static Jekyll site deployed on GitHub Pages at https://hermeticus.org. Most pages are fully static, but the /books/ page now depends on a separate Cloudflare Worker to read live book data from Square and create hosted checkout sessions. The site itself never stores Square secrets and never handles payment card entry.
Major Components and Boundaries
- GitHub Pages Jekyll site
Stores page content, layouts, styles, and browser-side catalog code. It renders the page shell for
/books/, loadsassets/js/main.js, and points that code at the deployed worker URL through_config.yml. - Cloudflare Worker
Lives in
integrations/square-catalog-worker/. It exposes:GET /catalogfor public catalog readsPOST /checkoutfor server-validated cart checkout creation The worker is the only component that talks to Square APIs.
- Square Catalog API Source of item, category, image, and variation data.
- Square Inventory API Source of the current stock count for each published book at one configured Square location.
- Square Checkout API Creates Square-hosted payment links for validated multi-item carts.
Interfaces and Data Flow
- A visitor opens
/books/onhermeticus.org. - The static page shell from
pages/books.mdand_includes/square-catalog.htmlloads. assets/js/main.jsreadssquare_catalog_api_basefrom_config.yml, restores any previously saved cart lines from browserlocalStorage, and requestsGET <worker>/catalog.- The worker checks Cloudflare edge cache.
- On a cache miss, the worker:
- paginates through Square
ListCatalogforITEM,CATEGORY, andIMAGE - extracts items that are publishable for v1
- retrieves inventory counts for candidate variation IDs at
SQUARE_LOCATION_ID - returns a compact JSON array with short keys
- caches that response at Cloudflare
- paginates through Square
- The browser renders cards with category, image links, Square description content, price, stock count, browse controls, and add-to-cart controls.
- Client-side search, category filtering, and sorting run entirely against the already loaded catalog array without further network requests.
- The browser persists cart lines in
localStorage, reconciles them against the freshly loaded catalog on page load, and silently drops lines that are no longer valid. - When the buyer checks out,
assets/js/main.jssendsPOST <worker>/checkoutwith variation IDs and requested quantities. - The worker bypasses the cached public payload, rebuilds current live availability from Square, validates the cart, and creates a Square-hosted payment link.
- The browser redirects the buyer to Square’s checkout page. On a
?checkout=successreturn, the client clears the saved cart and shows a success message.
The public catalog payload uses these keys:
iitem IDvvariation IDnnamepprice in minor unitsddescription. This contains Squaredescription_htmlwhen available, otherwise Square plaintext description data.ccategory namemimage URL listqquantity available
The checkout payload returns { "u": "<square-checkout-url>" } on success.
Storage and External Dependencies
- No database is used by the site or worker.
- Catalog browse results are cached at Cloudflare edge with a short TTL.
- The
/books/page stores cart state in browserlocalStorageunder a repo-owned key. This storage is client-side only and is treated as disposable convenience state, not a source of truth. - Secrets are stored only in Cloudflare Worker secrets:
SQUARE_ACCESS_TOKEN
- Non-secret worker configuration currently includes:
ALLOWED_ORIGINSSQUARE_ENVSQUARE_LOCATION_IDCATALOG_TTL_SECONDSSQUARE_VERSION
- Site-side worker location is configured in
_config.ymlthroughsquare_catalog_api_base. - External runtime dependencies:
- GitHub Pages / Jekyll
- Cloudflare Workers
- Square Catalog, Inventory, and Checkout APIs
Invariants
- The public Git repository contains no Square or Cloudflare secrets.
- Payment card entry never happens on
hermeticus.org; buyers complete payment on Square-hosted checkout. - Only items with exactly one sellable variation and positive tracked inventory at the configured Square location are published on
/books/. - Items with zero inventory or archived state disappear from the public catalog after cache refresh.
GET /catalogis cacheable;POST /checkoutmust validate against fresh Square data before creating a checkout link.- Browser code must sanitize Square description HTML before rendering it. Other catalog fields are rendered as text.
- Browser-stored cart lines must be reconciled against the latest live catalog payload before rendering or checkout.