# {{BUSINESS_NAME}}

Generated by Salix Commerce `{{GENERATOR_VERSION}}` from `nextjs-store` template `{{TEMPLATE_VERSION}}` on {{GENERATED_AT}}.

This is the intentionally neutral, SC10 dual-certified single-business commerce runtime. It includes strict typed configuration, server-only environment validation, catalog/inventory/cart/order/payment/admin contracts, generated Supabase migrations and seed data, server-only repository adapters, opaque guest capabilities, hosted Stripe Checkout, verified payment-event processing, Supabase Auth administrator sessions, role-gated operations, fulfillment, refund requests, immutable audit evidence, centralized visual tokens, and accessible empty/loading/error states.

When Supabase is blank, the public app builds and runs with certified empty catalog/cart/payment adapters while administration reports that it is unavailable. When configured and migrated, the public commerce routes and authenticated `/admin` surface share one business database. The signed fake provider is local/test-only and rejected in production. Stripe selection creates hosted one-time Checkout Sessions and changes payment state only after a verified provider event. There is still no tax or shipping-rate policy, transactional email, client content, or visual identity.

Edit `src/config/application.ts` for approved public business configuration. Never put credentials in that file. The initial normalized configuration is fingerprinted in provenance; later client-owned edits do not rewrite provenance. Server-only variable names are documented with blank values in `.env.example`.

## Start

```shell
{{PACKAGE_MANAGER}} install
{{PACKAGE_MANAGER}} run setup
{{PACKAGE_MANAGER}} run dev
```

For local catalog data, install Docker, then run:

```shell
npx supabase@2.109.1 start
npx supabase@2.109.1 db reset --local
npx supabase@2.109.1 status -o env
```

Copy the local `API_URL`, `PUBLISHABLE_KEY`, and `SERVICE_ROLE_KEY` into `SALIX_SUPABASE_URL`, `SALIX_SUPABASE_PUBLISHABLE_KEY`, and `SALIX_SUPABASE_SERVICE_ROLE_KEY` in an uncommitted `.env.local` file. Never expose the service-role key through `NEXT_PUBLIC_*` variables.

Create administrator identities through Supabase Auth administration, not public sign-up. Then add the Auth user to the protected single-business membership table:

```sql
insert into public.admin_users (user_id, role, display_name)
select id, 'owner', 'Business Owner'
from auth.users
where email = 'owner@example.com';
```

Available roles are `owner`, `manager`, and `operator`. Owners and managers can edit catalog data and request refunds; operators can adjust inventory and move paid orders through `processing` to `fulfilled`. No role or permission is read from user-editable Auth metadata.

To certify payments locally without Stripe, set `SALIX_PAYMENT_PROVIDER=fake` and a random 32+ character `SALIX_FAKE_PAYMENT_SECRET`. The fake provider never calls a payment network and cannot run when `NODE_ENV=production`.

For Stripe test mode, set the Supabase pair plus:

```text
SALIX_PAYMENT_PROVIDER=stripe
SALIX_CHECKOUT_BASE_URL=http://localhost:3000
SALIX_STRIPE_SECRET_KEY=<server test key>
SALIX_STRIPE_WEBHOOK_SECRET=<endpoint or Stripe CLI signing secret>
```

Forward only the supported event families to the raw-body endpoint:

```shell
stripe listen --forward-to localhost:3000/api/webhooks/stripe --events checkout.session.completed,checkout.session.async_payment_succeeded,checkout.session.async_payment_failed,checkout.session.expired,refund.created,refund.updated
```

Use HTTPS for `SALIX_CHECKOUT_BASE_URL` outside local development. A Checkout redirect never marks an order paid; the verified webhook transaction remains authoritative. The current order total is merchandise only until explicit tax and shipping-rate policy is implemented.

## Verify

```shell
{{PACKAGE_MANAGER}} run verify
```

Project provenance is recorded in `.salixcommerce.json`. Do not place secrets in that file.
