61 Commits
Author SHA1 Message Date
tanshu d04314ab1c Deploy with rootless podman + Quadlet on emily
Retargets the build and the playbook off rootful Docker on monoco, following the
conventions already in place on emily's other services: Quadlet units in
~/.config/containers/systemd, per-service data in ~/podman-data, and a shared
Caddy that every service registers itself with — a network drop-in plus a
marked block in its Caddyfile. Nothing is published on the host; Caddy reaches
the containers by name over mozimo_net.

- Makefile: podman build + push instead of docker buildx, PLATFORMS=linux/arm64
  (both hosts are aarch64). podman has no built-in QEMU the way buildx's builder
  image does, so a foreign-platform failure now points at qemu-user-static.
- deploy.sh: pass COMMIT= to make, which the Makefile actually reads; it was
  passing TAG=, so the tag silently came from `git rev-parse` instead.
- ansible: hosts emily, become false, XDG_RUNTIME_DIR for rootless podman and
  systemctl --user. Docker modules become Quadlet templates with user-service
  handlers, and the network role now ships mozimo.network plus the Caddy drop-in
  rather than calling docker_network.
- UserNS=keep-id maps the container's uid 1000 (node) and root (vince) onto the
  host user, so PocketBase and Vince write host-owned files instead of
  subuid-owned ones; the play asserts the pinned uid still matches the host.
- ansible/README.md: the unit layout, the service-registration convention, and
  the monoco -> emily migration (PocketBase 23 MB + Vince 119 MB, DNS cutover,
  rollback).

Verified by a check-mode rehearsal against emily (13 ok / 8 changed / 0 failed)
and a disposable Quadlet unit on that host proving the uid mapping, the
EnvironmentFile and the isolated network. The real build and cutover have not
been run.
2026-10-16 10:11:39 +05:30
tanshu 1bc1d5f753 Seed the dev store's collections from a production snapshot
The AFK half of the wayfinder ticket "Seed the dev store from the live
catalogue". Products, metafields and images still come from the CSV export —
the CSV re-hosts images for free — but collection membership cannot: the
Collection column is import-only, takes one collection per product, and this
catalogue runs 1.6 memberships per product across 16 collections.

- scripts/seed-dev-store.mjs (`npm run seed:dev-store`): creates each missing
  collection with its members in one call and publishes it. Uses
  CollectionCreateInput.sources because collectionAddProducts is deprecated at
  2026-10, and publishes because collectionCreate leaves a collection
  unpublished — invisible to the Storefront API the dev store exists to serve.
  Idempotent, never deletes, reports handles it cannot find (which is how a
  partial CSV import shows up), and is a dry run unless given --apply.
- assets/dev-store-seed.json: the baseline the seed is checked against and the
  membership map it consumes — 61 products with option values, weights and
  product types, 16 collections with 100 memberships, and the 10 metafield
  definitions that must exist before the import.
- The ticket now records what the probes settled: the option shape is readable
  from the Storefront API (all 61 use Option1 name=Title; 22 are `Default
  Title`, 39 carry real values, so the import must not normalise), and the
  repo's production credentials are Storefront-scoped only — `products`,
  `collections` and `productsCount` are Access denied without read_products —
  so the ticket's "Admin API script using the credentials the repo already
  mints" was never available. A dev-store custom app is required instead.
2026-10-16 10:11:32 +05:30
tanshu de0553d0d4 Wayfinder: chart the Shopify headless commerce map
The route from "mozimo.in displays Shopify products" to "mozimo.in sells them",
as a plan with a phase spine and gates, plus the open decision tickets that
still shape it and the evidence they rest on.

- .scratch/shopify-headless-commerce/: plan.md (phases and gates), map.md (the
  wayfinder map), 10 open decision tickets
- CONTEXT.md: Storefront / Theme store / Cart / Parity vocabulary
- docs/adr/0001-0003: Checkout stays Shopify-hosted, one Variant per product,
  the checkout domain stays shop.mozimo.in
- docs/research/ and docs/shopify-catalog-inventory.md: verified store facts,
  the Cart API probe, and the catalogue inventory

Raw Shopify doc scrapes under .scratch/shopify-research/ are ignored: they are
working material, not record.
2026-10-14 09:00:42 +05:30
tanshu bb0c78fec5 Phase 0: pin Storefront API 2026-10, carry Variant GIDs, serve last-good data
Foundations for the phases that write. The Storefront served a retired API
version (2025-01 was answered as 2025-10) and no product carried a merchandise
ID, so nothing could be carted.

- Pin the Storefront API to 2026-10 and log the version Shopify actually
  served, so retired-version drift is visible instead of silent. Drop the
  stale predictiveSearch comment.
- ShopProduct carries the Variant GID and per-variant price, replacing the
  product-level price range with the Variant as the one source of truth.
  Products without a Variant are dropped rather than shown uncartable.
- Send Shopify-Storefront-Buyer-IP from the buyer's request, and omit it when
  no request is in scope (builds, scripts).
- Standardise on the minted OAuth token; the static storefront token is a
  warned legacy fallback.
- Persist the last known-good payloads to disk beside the token cache, so a
  Shopify outage serves stale real commerce data rather than the bundled
  Editorial catalog. Verified against an unreachable store: a product absent
  from the Editorial catalog still rendered from last-good data.
- Fix a latent 500: a failed OAuth mint threw out of gql (it ran outside the
  try). Transport failures now report status 0 and gql fails closed.
- Point the seasonal Rakhi card at the gift collection; its
  /products/rakhi-bark-box-200gm handle is dead and no Rakhi product remains.
2026-10-14 08:58:50 +05:30
tanshu 1120a35fd1 Matt Pocock Skills setup 2026-10-13 12:26:03 +00:00
tanshu 4a3863a809 301 from www to apex 2026-10-13 12:18:44 +00:00
tanshu 56d1cfda7a Get Tag line, Nutrition and Ingredients from Shopify. 2026-10-13 12:03:34 +00:00
tanshu 1419c1d9ee Reject Next-Action probes before the SSR handler
POST / with a React server-actions header is not a request this app
makes — TanStack server functions POST to /_serverFn/<id>. Left alone
the transform stream sat open until the 120s lifetime timer force-cleaned
it, surfacing as a fatal uncaught exception in Sentry (event e267e264,
release 84dffa8). Now answered 404 in 9ms; normal pages unaffected.
2026-09-12 16:17:25 +05:30
tanshu 84dffa8451 Promoted to main website. 2026-09-06 16:58:31 +00:00
tanshu 3929d3f0b2 Vince fixed 2026-09-06 16:34:23 +00:00
tanshu 605b4b16cc Wrong image 2026-09-06 16:09:46 +00:00
tanshu e0eb577e3e Google analytics integration.
Sentry.io integration.
Vince integration.
Region-scoped consent (denied-by-default in EU/EEA/UK/CH, granted elsewhere, DPDP-friendly notice)
2026-09-06 16:03:13 +00:00
tanshu 43c6fbe437 Hero: banner-3 (bonbon field) replaces the matcha campaign ad (Q3)
- composed hero stays split ivory/copy + image; bonbons carry the
  mustard/oxblood/copper of the r9 direction; Shop Chocolate opens
  same-tab now
- preview mock shown and approved before this commit; swap again when
  the r9 shoot lands
2026-09-06 15:22:50 +05:30
tanshu 296c05cf88 PB-driven editorial copy + Hampers & Boxes category (Q1a, Q2, Q5)
- collection_rows: hampers-boxes row (seed default + ensure-row migration);
  /chocolate shows the button, /collections/hampers-boxes gets the two-tone
  hero (last-word script rule) + live Shopify hampers + row blurb as lead
- gifting_page: tabs/hampers/seasonal heading fields (seed + fill-missing
  migration, never overwrites admin edits); gifting.tsx consumes them
- site_settings: home seasonal + universe copy keys (seed + ensure-keys
  migration); index loader passes them to SeasonalTeaser/UniverseSection
- hero lead on collection pages falls back to the PB row blurb
2026-09-06 15:22:50 +05:30
tanshu 06f6e75b57 Keep shoppers on mozimo.in: internalize all marketing links
- gifting tab CTAs now point at our /collections pages (seed defaults +
  one-off PB migration rewriting shop.mozimo.in cta_urls, idempotent)
- Hero/Footer/our-world/journal 'shop' links -> /chocolate; bespoke
  bulk-ordering -> /gifting#corporate-bulk
- still on Shopify (deliberate, until Phase 2): PDP buy button, Header
  bag+account, footer policies
2026-09-06 14:48:41 +05:30
tanshu 2524f0c46f Caddy role: single files/Caddyfile.j2 template (overlord pattern)
- template moved to ansible/files/Caddyfile.j2, tasks folded into main.yaml
2026-09-06 09:01:46 +00:00
tanshu c4a6425926 Caddy: adopt dual-role snippet (PB api+admin on main host), relative PB file urls
- www host: /_* and /api/* proxy to pocketbase :8090, everything else to
  the TanStack app; redir /_ /_/ for the admin path
- cms host unchanged: redir / -> /_/
- migration: legacy per-host marker blocks are removed before the new
  combined block is installed
- cms.ts: PB file urls are now same-origin relative (/api/files/...) —
  browsers could never load the old 127.0.0.1:8090 urls; validated the
  rendered Caddyfile with caddy:2
2026-09-06 14:22:09 +05:30
tanshu f5d5dcac94 vars: pb_root flag on the cms caddy host (dashboard at /) 2026-09-06 14:16:57 +05:30
tanshu c5e89f0f90 Caddy: PocketBase dashboard reachable at cms host root (redir / -> /_/)
- snippet generation moved to a j2 template; per-host pb_root flag
- cms.mozimo.in emits 'redir / /_/' before reverse_proxy (pattern from
  overlord's Caddyfile); other hosts unchanged
- snippets now update in place (blockinfile idempotency) instead of
  skipping when the desired block changed
2026-09-06 14:15:52 +05:30
tanshu f68ddad6f3 Fix seed script unreadable in image: COPY --chmod applied 0644 to the auto-created /app/scripts dir (unsearchable for the node user → MODULE_NOT_FOUND). Seed now lives at /app/pb-seed.mjs. 2026-09-06 13:48:15 +05:30
tanshu 7d29886975 cleanup 2026-09-06 08:02:01 +00:00
tanshu 134f0b0a7a Deploy workflow: commit-id image tags, guarded deploy.sh, opt-in prune
- Makefile builds from 'git archive HEAD' (stale-remote-HEAD impossible):
  tags registry.tanshu.com/mozimo:<short-commit> + :main; build-check target
  verifies both architectures without pushing
- deploy.sh: refuses dirty tracked tree / HEAD != origin/main (--force to
  bypass), ff-only pull, passes the commit as image_tag to ansible,
  --prune flag for opt-in image cleanup
- ansible: docker_image uses image_tag extra-var (falls back to tag),
  prune task keeps the 3 newest mozimo images, mozimo-repo only
2026-09-06 13:21:16 +05:30
tanshu 424a2b016a Updated pocketbase errors. 2026-09-06 07:18:40 +00:00
tanshu c80c2b0b12 cms typo 2026-09-06 06:52:23 +00:00
tanshu 328a1a23e0 Agent skills
Prettier
eslint
shopify
2026-09-06 06:38:04 +00:00
tanshu ba93b829c4 gifting pill boxes to image buttons. 2026-09-04 11:40:11 +00:00
tanshu bc5ced1843 updates 2026-09-04 11:38:24 +00:00
tanshu f4db22e828 missed a file 2026-09-03 10:44:31 +00:00
tanshu c121e0ca0a Updated docker 2026-09-03 10:40:55 +00:00
tanshu 09cbe61890 node image does not have apt 2026-09-03 10:24:13 +00:00
tanshu bd801a1f4f wrong node 2026-09-03 10:22:12 +00:00
tanshu 7bc3e7fa76 Pointing to the wrong repository. 2026-09-03 10:19:42 +00:00
tanshu 7961a3d2a6 deepseek harness 2026-09-03 10:11:31 +00:00
tanshu cbdcf74bfc SEO 2026-04-21 02:08:09 +00:00
tanshu 4930e6c6d2 SEO Improvements. 2026-04-19 14:07:23 +00:00
tanshu ed959df5e9 Updated hosts for non www usage 2026-04-19 10:11:30 +00:00
tanshu fc94ae7bb2 Updated the makefile 2026-04-19 09:58:59 +00:00
tanshu e94dec0036 Performance improvements and Dockerfile update 2026-04-19 09:54:47 +00:00
tanshu 31f88749f9 Moved to tanstack start from nextjs using google antigravity 2026-04-19 08:15:50 +00:00
tanshu 7b1ee49d11 Added google tag
Added ansible
Added deploy.sh
2025-10-04 14:53:45 +00:00
tanshu 67411b3972 Update build 2025-10-04 11:31:00 +00:00
tanshu e3396231b3 Pipiline for docker build 2025-10-04 05:08:49 +00:00
ABasral a2727d3f5d links uopdated 2025-09-13 17:25:09 +05:30
ABasral 52ded64b40 fixes 2025-09-12 13:37:27 +05:30
ABasral b06bb213b7 updates 2025-09-12 13:34:25 +05:30
Ayush b1cdd39d8f Update README.md 2025-08-25 14:29:29 +05:30
bharti 0c3f73dab9 video done 2025-08-25 10:32:43 +05:30
bharti 41a5e9e434 video changes 2025-08-24 23:53:13 +05:30
Ayush ffc9a4a9e6 Update README.md 2025-08-21 00:12:07 +05:30
bharti 683d4ad0ed video url 2025-08-20 23:41:07 +05:30