5. Backend validates the checkout session token, queries order data through Admin GraphQL, reads the `$app:dreame_activity` Metaobject config, checks order-level idempotency, calls Dreame status API, then calls Dreame push API.
6. On success, backend returns `success`, `redirectUrl`, and localized `buttonText`.
7. Extension renders a button and opens `redirectUrl` in the current window.
Failures return `{ "success": false }`; the extension renders nothing and does not block the native Thank You Page.
## Local Setup
The Shopify CLI was not available in this workspace, and remote `npm create @shopify/app@latest` execution was blocked by local safety policy. The project has therefore been initialized as a local scaffold matching the requested Shopify Remix structure.
When network access is available:
```bash
cd "/Users/jason/Downloads/myproject/Shopify 插件开发/dreame-shopify-app"
npm install
cp .env.example .env
npx prisma generate
npx prisma migrate dev
shopify app dev
```
Install the app to the development shop:
```text
function-613wh0ez.myshopify.com
```
## Environment
Copy `.env.example` to `.env` and fill Shopify credentials:
The optional script upserts the singleton Metaobject entry. The definition itself is managed through `shopify.app.toml` and applied by Shopify CLI during `shopify app dev` or `shopify app deploy`.
CORS headers are returned for `POST` and `OPTIONS`; source trust relies on Shopify checkout session token validation.
## Dreame Signing
All third-party requests include:
-`dreame-api-app-id`
-`dreame-api-timestamp`
-`dreame-api-sign`
Signature:
```text
sign = MD5(bodyString + timestamp + api_secret)
```
The implementation serializes the payload once with `JSON.stringify(payload)`. The exact same `bodyString` is used both for signing and as the `fetch` body.
## Mock Mode
Default mock behavior:
- Status API returns `code=0` and `data.status=true`.
Switch to live calls only after third-party endpoints and credentials are available:
```env
THIRD_PARTY_MODE=live
```
## Database
Development uses SQLite:
```env
DATABASE_URL="file:./dev.sqlite"
```
Production should use Postgres. The same Prisma schema applies after changing the datasource provider and connection string as part of production hardening.
Tables added by this scaffold:
-`ActivityPushLog`: one row per status/push attempt or failure.
-`ActivityPushIdempotency`: unique key on `shop + orderId + activityId`; prevents duplicate push for the same order and activity.
Logs are sanitized before persistence and must not store `api_secret` or `dreame-api-sign`.
## Checkout UI Extension
Location:
```text
extensions/thank-you-activity
```
Target:
```text
purchase.thank-you.block.render
```
Capabilities:
```toml
[extensions.capabilities]
network_access = true
```
Set the extension setting `app_url` to the public HTTPS backend URL. During `shopify app dev`, this is the tunnel URL produced by Shopify CLI.
`purchase.thank-you.block.render` is a valid latest Thank You Page block target. Merchants can control placement in the checkout and accounts editor; changing to a static target such as `purchase.thank-you.header.render-after` requires TOML/code review and redeployment.
The extension sets `default_placement = "ORDER_STATUS1"` so the first suggested placement is above the order status card. Merchants can still move the block in the checkout and accounts editor.