hank-vibe Claude Opus 5 commited on
Commit
2caaa2b
Β·
1 Parent(s): 0984f9f

docs: update Space references from solora-hq/Mixly to jay-hank/mixly

Browse files

The Space was created and named jay-hank/mixly, on a different HF
account than Tierly's (solora-hq). Update all URLs, the S3 endpoint
namespace, the first-time-setup steps (Space already exists), and the
HF_SPACE_ID / sync-env.mjs default-value mismatches vs the in-code
defaults. Add a risk note about HF Storage Bucket availability on a
free, non-Pro account and the ephemeral-filesystem data-loss exposure
that follows if it is unavailable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Files changed (1) hide show
  1. DEPLOY.md +48 -27
DEPLOY.md CHANGED
@@ -1,37 +1,57 @@
1
  # Mixly on Hugging Face Spaces β€” deploy & operations
2
 
3
- The Space (`solora-hq/Mixly`) is a **Docker** host. Its `Dockerfile` clones the
4
  **private** GitHub repo `phamdung2209/Mixly` at build time and runs the Next.js app.
5
 
6
- Public URL: `https://solora-hq-mixly.hf.space`
7
 
8
- > ⚠️ **Data isolation.** `solora-hq` also hosts **Tierly**, which is LIVE with real
9
- > merchant data. Mixly's `DATABASE_URL`, `S3_BUCKET`, and Space name are a
10
- > completely separate set of identifiers from Tierly's β€” never copy a value from
11
- > Tierly's `DEPLOY.md` here. Concretely: DB path is `/data/mixly.db` (not
12
- > `tierly.db`), bucket is `Mixly-storage` (not `Tierly-storage`), Space is
13
- > `solora-hq/Mixly` (not `solora-hq/Tierly`). Pointing Mixly at any of Tierly's
14
- > identifiers risks corrupting or leaking live merchant data.
 
 
 
15
 
16
  ---
17
 
18
- ## 0. First-time setup (do this once β€” the Space doesn't exist yet)
19
 
20
- 1. **Create the Space**: https://huggingface.co/new-space β†’ Owner `solora-hq`,
21
- Space name `Mixly`, **SDK: Docker**, visibility your choice, no template.
22
- 2. **Add the remote and push this repo**:
 
23
  ```
24
- git remote add origin https://huggingface.co/spaces/solora-hq/Mixly
25
  git push -u origin main
26
  ```
27
  The first build will fail (or crash-loop) until the secrets in Β§2 are set β€”
28
  that's expected, HF just needs a repo to attach the build to.
29
- 3. **Create the S3 storage bucket**: HF β†’ your `solora-hq` org β†’ **Storage** β†’
30
  **New bucket** β†’ name it exactly `Mixly-storage` (bare name, no slashes). Double
31
- check it is not `Tierly-storage`.
32
- 4. **Set every secret in Β§2 below** (Space β†’ Settings β†’ Variables and secrets),
 
33
  then Space β†’ Settings β†’ **Factory rebuild**.
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  ---
36
 
37
  ## 1. GitHub token (required β€” the repo is private)
@@ -66,10 +86,11 @@ Then add it to the Space as a **build secret**:
66
  | `SHOPIFY_API_SECRET` | β€³ (secret) |
67
  | `NEXT_PUBLIC_SHOPIFY_API_KEY` | **same value as** `SHOPIFY_API_KEY` |
68
  | `SHOPIFY_SCOPES` | `read_orders,read_products,write_discounts` (match `shopify.app.toml`) |
69
- | `SHOPIFY_APP_URL` | `https://solora-hq-mixly.hf.space` |
70
  | `SHOPIFY_API_VERSION` | `2026-07` |
71
  | `DATABASE_URL` | `file:/data/mixly.db` (persistent mount β€” see Β§3) |
72
  | `SESSION_ENCRYPTION_KEY` | `openssl rand -hex 32`. **Set once, never change** (rotating it forces every store to re-auth). |
 
73
 
74
  ### Ops Console + DB access (`/ops`, `/ops/studio`)
75
  | Name | Value |
@@ -77,21 +98,20 @@ Then add it to the Space as a **build secret**:
77
  | `OPS_ALLOWLIST` | comma-separated emails allowed into `/ops` |
78
  | `AUTH_SECRET` | `npx auth secret`. Keep stable (else your `/ops` sessions drop). |
79
  | `AUTH_GOOGLE_ID` | Google Cloud Console β†’ OAuth client ID |
80
- | `AUTH_GOOGLE_SECRET` | β€³ (redirect URI: `https://solora-hq-mixly.hf.space/api/auth/callback/google`) |
81
 
82
  ### DB backup (Β§4) β€” HF Storage Bucket via S3 API
83
  | Name | Value |
84
  |---|---|
85
- | `S3_ENDPOINT` | `https://s3.hf.co/solora-hq` (gateway scoped to the namespace) |
86
  | `S3_BUCKET` | `Mixly-storage` (bare bucket name β€” **not** `Tierly-storage`) |
87
  | `S3_ACCESS_KEY_ID` | `HFAK…` β€” HF **Access Tokens** β†’ token (Write) β†’ dropdown β†’ **Generate S3 credentials** |
88
  | `S3_SECRET_ACCESS_KEY` | β€³ (shown once) |
89
  | `HF_TOKEN` | HF bearer token β€” used to rebuild/restart the Space from `/ops/backup` after a DB restore (Β§4), and by `scripts/sync-env.mjs` (Β§5), NOT the S3 creds |
90
 
91
  ### Optional (features degrade gracefully when unset)
92
- `SENTRY_DSN`, `HF_SPACE_ID` (defaults to `solora-hq/Mixly` in code β€” only set if
93
- the Space is ever renamed), `GITHUB_REPO` (overrides the clone source; the
94
- Dockerfile's `ARG GITHUB_REPO` build arg already defaults to the right repo).
95
 
96
  Mixly has **no** Crisp chat, QStash, or email (Resend) integration β€” unlike
97
  Tierly, none of `NEXT_PUBLIC_CRISP_WEBSITE_ID`, `QSTASH_*`, `RESEND_API_KEY`,
@@ -125,7 +145,7 @@ Network-only (no mount), so it never blocks Space scheduling.
125
  only in Space secrets. Keep it β€” a restored DB with a lost/rotated key can't
126
  decrypt stored Shopify tokens (the app then just re-exchanges them, no data loss,
127
  but avoid churn).
128
- - **Bucket:** `solora-hq/Mixly-storage`. Objects: `latest.db` (overwritten in place β€”
129
  no history growth) + `snapshots/mixly-YYYY-MM-DD.db` (daily, pruned after 30 days).
130
  - **Schedule:** in-process β€” an initial backup ~1 min after boot, then hourly, plus a
131
  debounced write after each DB change and a final flush on SIGTERM (see
@@ -144,9 +164,10 @@ Network-only (no mount), so it never blocks Space scheduling.
144
  - **Redeploy the web app:** push to GitHub `main`, then in the Space use
145
  **Settings β†’ Factory rebuild** (re-clones latest `main`).
146
  - **Push local env vars as Space secrets:** `HF_TOKEN=… node scripts/sync-env.mjs
147
- [.env.production.local] [solora-hq/Mixly]` (both args optional, those are the
148
- defaults) β€” reads `KEY=value` lines and pushes each as a secret via the HF API.
149
- Changes apply on the next rebuild/restart.
 
150
  - **Deploy the Shopify Function / extensions:** that is a *separate* target, run from
151
  your machine (needs the Shopify CLI + Partner auth) β€” `npm run app:deploy`. The
152
  container also runs this non-fatally during a Space build (see Dockerfile), gated
 
1
  # Mixly on Hugging Face Spaces β€” deploy & operations
2
 
3
+ The Space (`jay-hank/mixly`) is a **Docker** host. Its `Dockerfile` clones the
4
  **private** GitHub repo `phamdung2209/Mixly` at build time and runs the Next.js app.
5
 
6
+ Public URL: `https://jay-hank-mixly.hf.space`
7
 
8
+ > ⚠️ **Data isolation.** Mixly lives under the `jay-hank` HF account β€” a
9
+ > **different account** from `solora-hq`, which hosts **Tierly** and is LIVE with
10
+ > real merchant data. Mixly's `DATABASE_URL`, `S3_BUCKET`, `S3_ENDPOINT`, and Space
11
+ > name are a completely separate set of identifiers from Tierly's β€” never copy a
12
+ > value from Tierly's `DEPLOY.md` here. Concretely: DB path is `/data/mixly.db`
13
+ > (not `tierly.db`), bucket is `Mixly-storage` (not `Tierly-storage`) under the
14
+ > `jay-hank` namespace (not `solora-hq`), Space is `jay-hank/mixly` (not
15
+ > `solora-hq/Tierly`). `jay-hank` has no access to `solora-hq` at all, so pointing
16
+ > Mixly at any of Tierly's identifiers won't just risk corrupting or leaking live
17
+ > merchant data β€” it will most likely just fail outright.
18
 
19
  ---
20
 
21
+ ## 0. First-time setup (do this once β€” the Space already exists)
22
 
23
+ The Space `jay-hank/mixly` has already been created (Docker SDK) on the
24
+ `jay-hank` HF account. What's left:
25
+
26
+ 1. **Add the remote and push this repo**:
27
  ```
28
+ git remote add origin https://huggingface.co/spaces/jay-hank/mixly
29
  git push -u origin main
30
  ```
31
  The first build will fail (or crash-loop) until the secrets in Β§2 are set β€”
32
  that's expected, HF just needs a repo to attach the build to.
33
+ 2. **Create the S3 storage bucket**: HF β†’ your `jay-hank` account β†’ **Storage** β†’
34
  **New bucket** β†’ name it exactly `Mixly-storage` (bare name, no slashes). Double
35
+ check it is not `Tierly-storage`. Read the risk note below first β€” Storage
36
+ Buckets may not be available on this account's plan.
37
+ 3. **Set every secret in Β§2 below** (Space β†’ Settings β†’ Variables and secrets),
38
  then Space β†’ Settings β†’ **Factory rebuild**.
39
 
40
+ > 🚧 **Risk: HF Storage Buckets may not be available on a free, non-Pro account.**
41
+ > `jay-hank` is a free, non-Pro account. This matters more than it sounds: the HF
42
+ > free tier has an **ephemeral** filesystem, so without a working S3 bucket the
43
+ > SQLite database is **destroyed on every rebuild, restart, or wake-from-sleep** β€”
44
+ > the app would silently lose every merchant's bundles, settings, and stats.
45
+ > Tierly has already suffered exactly this data-loss failure once, which is why
46
+ > the restore-on-boot mechanism (Β§4) exists. Before treating this deployment as
47
+ > production-ready, confirm that a bucket named `Mixly-storage` can actually be
48
+ > created under the `jay-hank` namespace and that `S3_ACCESS_KEY_ID` /
49
+ > `S3_SECRET_ACCESS_KEY` work against `https://s3.hf.co/jay-hank`. If HF storage
50
+ > buckets aren't available on this plan, the options are: enable HF Persistent
51
+ > Storage (paid), upgrade the account, or point the backup at a different
52
+ > S3-compatible provider (`src/lib/s3.ts` speaks plain S3, so any S3-compatible
53
+ > endpoint should work).
54
+
55
  ---
56
 
57
  ## 1. GitHub token (required β€” the repo is private)
 
86
  | `SHOPIFY_API_SECRET` | β€³ (secret) |
87
  | `NEXT_PUBLIC_SHOPIFY_API_KEY` | **same value as** `SHOPIFY_API_KEY` |
88
  | `SHOPIFY_SCOPES` | `read_orders,read_products,write_discounts` (match `shopify.app.toml`) |
89
+ | `SHOPIFY_APP_URL` | `https://jay-hank-mixly.hf.space` |
90
  | `SHOPIFY_API_VERSION` | `2026-07` |
91
  | `DATABASE_URL` | `file:/data/mixly.db` (persistent mount β€” see Β§3) |
92
  | `SESSION_ENCRYPTION_KEY` | `openssl rand -hex 32`. **Set once, never change** (rotating it forces every store to re-auth). |
93
+ | `HF_SPACE_ID` | `jay-hank/mixly` β€” the in-code default (`src/lib/ops/backup.ts`) is still `solora-hq/Mixly`, which is wrong for this deployment, so this must be set explicitly. |
94
 
95
  ### Ops Console + DB access (`/ops`, `/ops/studio`)
96
  | Name | Value |
 
98
  | `OPS_ALLOWLIST` | comma-separated emails allowed into `/ops` |
99
  | `AUTH_SECRET` | `npx auth secret`. Keep stable (else your `/ops` sessions drop). |
100
  | `AUTH_GOOGLE_ID` | Google Cloud Console β†’ OAuth client ID |
101
+ | `AUTH_GOOGLE_SECRET` | β€³ (redirect URI: `https://jay-hank-mixly.hf.space/api/auth/callback/google`) |
102
 
103
  ### DB backup (Β§4) β€” HF Storage Bucket via S3 API
104
  | Name | Value |
105
  |---|---|
106
+ | `S3_ENDPOINT` | `https://s3.hf.co/jay-hank` (gateway scoped to the namespace) |
107
  | `S3_BUCKET` | `Mixly-storage` (bare bucket name β€” **not** `Tierly-storage`) |
108
  | `S3_ACCESS_KEY_ID` | `HFAK…` β€” HF **Access Tokens** β†’ token (Write) β†’ dropdown β†’ **Generate S3 credentials** |
109
  | `S3_SECRET_ACCESS_KEY` | β€³ (shown once) |
110
  | `HF_TOKEN` | HF bearer token β€” used to rebuild/restart the Space from `/ops/backup` after a DB restore (Β§4), and by `scripts/sync-env.mjs` (Β§5), NOT the S3 creds |
111
 
112
  ### Optional (features degrade gracefully when unset)
113
+ `SENTRY_DSN`, `GITHUB_REPO` (overrides the clone source; the Dockerfile's
114
+ `ARG GITHUB_REPO` build arg already defaults to the right repo).
 
115
 
116
  Mixly has **no** Crisp chat, QStash, or email (Resend) integration β€” unlike
117
  Tierly, none of `NEXT_PUBLIC_CRISP_WEBSITE_ID`, `QSTASH_*`, `RESEND_API_KEY`,
 
145
  only in Space secrets. Keep it β€” a restored DB with a lost/rotated key can't
146
  decrypt stored Shopify tokens (the app then just re-exchanges them, no data loss,
147
  but avoid churn).
148
+ - **Bucket:** `jay-hank/Mixly-storage`. Objects: `latest.db` (overwritten in place β€”
149
  no history growth) + `snapshots/mixly-YYYY-MM-DD.db` (daily, pruned after 30 days).
150
  - **Schedule:** in-process β€” an initial backup ~1 min after boot, then hourly, plus a
151
  debounced write after each DB change and a final flush on SIGTERM (see
 
164
  - **Redeploy the web app:** push to GitHub `main`, then in the Space use
165
  **Settings β†’ Factory rebuild** (re-clones latest `main`).
166
  - **Push local env vars as Space secrets:** `HF_TOKEN=… node scripts/sync-env.mjs
167
+ .env.production.local jay-hank/mixly` β€” reads `KEY=value` lines and pushes each
168
+ as a secret via the HF API. The script's built-in default Space is still
169
+ `solora-hq/Mixly` (wrong for this deployment), so always pass `jay-hank/mixly`
170
+ explicitly as the second arg. Changes apply on the next rebuild/restart.
171
  - **Deploy the Shopify Function / extensions:** that is a *separate* target, run from
172
  your machine (needs the Shopify CLI + Partner auth) β€” `npm run app:deploy`. The
173
  container also runs this non-fatally during a Space build (see Dockerfile), gated