diff --git a/README.md b/README.md index b3136aa..2b827b5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,11 @@ You need [Node.js](https://nodejs.org/) v20.19.0 or higher and a [Base44 account | --- | --- | --- | --- | | [Trellix](./trellix/) | Trello-style task and project management. | React, Vite | [Trellix live demo](https://trellix-example-64ad1623.base44.app/). | | [Buzz](./buzz/) | AI browser sidekick extension for Chrome and Firefox. | WXT, React | N/A | +| [Base44 Estates](./fullstack-react-router/) | Real-estate agency site: public SSR listings with edge caching, RLS-protected inquiries and favorites, an AI concierge. | React Router 7 (SSR), full-stack hosting | N/A | +| [Base44 CRM](./fullstack-tanstack-start/) | Private team sales CRM: owner-scoped RLS, pipeline kanban, SSR dashboards, an AI sales copilot. | TanStack Start (SSR), full-stack hosting | N/A | +| [Meridian](./fullstack-astro/) | Coffee-roaster storefront: edge-cached catalog, dynamic product pages, authenticated checkout and orders, an AI shopping concierge. | Astro 6 (SSR), full-stack hosting | N/A | + +> **Full-stack hosting (preview).** The three `fullstack-*` apps run their server code on Base44 full-stack hosting and pin preview builds of the SDK and CLI via npm aliases (`@base44-preview/sdk`, `@base44-preview/cli`) in their `package.json`. They move to `@base44/sdk` and `base44` at GA. See each app's README for what it showcases (SSR edge caching, RLS, agents). ## See also diff --git a/fullstack-astro/.gitignore b/fullstack-astro/.gitignore new file mode 100644 index 0000000..e35cdfd --- /dev/null +++ b/fullstack-astro/.gitignore @@ -0,0 +1,22 @@ +# Dependencies +node_modules + +# Build +dist +.wrangler +.astro + +# Environment +.env +.env.* +*.local +.dev.vars + +# Editor +.vscode +.idea +.DS_Store +*.swp + +# Base44 App Config +base44/.app.json* diff --git a/fullstack-astro/README.md b/fullstack-astro/README.md new file mode 100644 index 0000000..dc5d5b9 --- /dev/null +++ b/fullstack-astro/README.md @@ -0,0 +1,168 @@ +# Meridian — a full-stack storefront on Base44 + +**Meridian** is a small-batch coffee-roaster storefront, built with +**Astro 7** and deployed to **Base44 full-stack hosting** (Cloudflare Workers). +It's a real example app: a product catalog, dynamic product and category +pages, a client-side cart, an authenticated checkout that writes real orders, +per-user order history, and an AI shopping concierge. + +Its headline feature is **hybrid rendering with SSR edge caching**: the +catalog is server-rendered so prices and stock are always fresh (and the +public pages opt into Base44's shared edge cache), while pure-content pages +(`/about`, `/brewing`, the 404) are **prerendered to static HTML at build +time** and served by the asset layer before any Worker code runs. Everything +personalised is explicitly kept out of every cache. + +## What's in the box + +### Data model (`base44/entities/*.jsonc`) + +| Entity | Purpose | Row-Level Security | +| --- | --- | --- | +| **Product** | Coffees & gear (price, images, stock, roast, origin, tags, `active`/`draft`) | Public **read**; **create/update/delete** admin-only | +| **Category** | Catalog sections (single-origin, blends, decaf, gear) | Public **read**; writes admin-only | +| **Order** | Checkout line items, total, status, shipping address | **Owner-scoped**: a shopper reads/updates only their own orders (`created_by == {{user.email}}`); delete admin-only | +| **Review** | Star ratings + text on a product | Public **read**; **update/delete** owner-scoped (owner or admin) | + +RLS uses Base44's documented `"rls"` schema syntax +(`{ "created_by": "{{user.email}}" }`, `{ "user_condition": { "role": "admin" } }`, +`true`/`false`, and `$or`). Public read on Product/Category is precisely what +makes the catalog pages safe to edge-cache. + +### AI agent (`base44/agents/concierge.jsonc`) + +**Bean**, a warm shopping concierge that can **read** Product/Category/Review to +recommend coffees by taste and brew method, and **create/read** Order to help a +shopper check out — scoped via `tool_configs`. + +### Pages (`src/pages/`) + +| Route | What it is | Rendering | +| --- | --- | --- | +| `/` | Homepage: hero, featured rail, category nav, full catalog | SSR, **edge-cached** (public) | +| `/products/[slug]` | Dynamic product detail + reviews + review form | SSR, **edge-cached** (public) | +| `/category/[slug]` | Category listing | SSR, **edge-cached** (public) | +| `/about` | Brand story: values, numbers, how we roast | **Static (prerendered)** | +| `/brewing` | Brew guides: five tested recipes + cheat-sheet table | **Static (prerendered)** | +| `404` | Not-found page | **Static (prerendered)** `404.html` | +| `/cart` | Cart (client-side, localStorage) | SSR, `private, no-store` | +| `/checkout` | Auth-gated checkout; writes an Order | SSR, `private, no-store` | +| `/account/orders` | The signed-in shopper's order history | SSR, `private, no-store` | +| `/login` | **App-owned auth page** — email/password sign-in and sign-up (OTP verification) + Google OAuth | SSR, `private, no-store` | +| `/api/me`, `/api/reviews`, `/api/orders`, `/api/auth/*` | JSON endpoints (server SDK) | SSR, `private, no-store` | + +## Hybrid rendering (SSG + SSR on one deploy) + +Astro's `output: "server"` renders every page on demand by default; a page +opts out with `export const prerender = true`. Meridian uses all three speeds +deliberately, and each page carries a visible badge so you can tell them +apart: + +| Mode | Pages | Why | Badge | +| --- | --- | --- | --- | +| **Static (SSG)** | `/about`, `/brewing`, `404` | Pure editorial content — changes per deploy, not per request. Astro bakes them to plain HTML in `dist/client/` at build time, and Base44's asset layer serves them **before any Worker code runs**: no render, no database, no cache to warm. | `Prerendered · built at ` — frozen until the next deploy | +| **SSR + edge cache** | `/`, `/products/*`, `/category/*` | Live catalog data (prices, stock, reviews) that is identical for every visitor — rendered by the Worker, then cached at the edge for 5 minutes. | `Edge-cached · server-rendered at