@usequark/quark-create-app 1.23.11 → 1.23.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -26
  3. package/package.json +67 -55
  4. package/src/index.js +17 -17
  5. package/src/utils.js +1 -1
  6. package/templates/base-project/.cursor/rules/quark.mdc +17 -17
  7. package/templates/base-project/.github/copilot-instructions.md +5 -5
  8. package/templates/base-project/.github/skills/project-context/SKILL.md +6 -6
  9. package/templates/base-project/CLAUDE.md +12 -12
  10. package/templates/base-project/README.md +3 -3
  11. package/templates/base-project/apps/web/next.config.js +5 -5
  12. package/templates/base-project/apps/web/package.json +5 -5
  13. package/templates/base-project/apps/web/src/app/_components/HomeThemeToggle.js +1 -1
  14. package/templates/base-project/apps/web/src/app/api/auth/apple/route.js +2 -2
  15. package/templates/base-project/apps/web/src/app/api/auth/google/route.js +2 -2
  16. package/templates/base-project/apps/web/src/app/api/auth/refresh/route.js +1 -1
  17. package/templates/base-project/apps/web/src/app/api/auth/register/route.js +3 -3
  18. package/templates/base-project/apps/web/src/app/api/auth/token/route.js +2 -2
  19. package/templates/base-project/apps/web/src/app/api/csrf/route.js +1 -1
  20. package/templates/base-project/apps/web/src/app/api/device/register/route.js +2 -2
  21. package/templates/base-project/apps/web/src/app/api/error-handler.js +1 -1
  22. package/templates/base-project/apps/web/src/app/api/files/[id]/route.js +2 -2
  23. package/templates/base-project/apps/web/src/app/api/files/route.js +2 -2
  24. package/templates/base-project/apps/web/src/app/api/health/route.js +2 -2
  25. package/templates/base-project/apps/web/src/app/api/users/[id]/route.js +2 -2
  26. package/templates/base-project/apps/web/src/app/api/users/me/route.js +2 -2
  27. package/templates/base-project/apps/web/src/app/api/users/route.js +2 -2
  28. package/templates/base-project/apps/web/src/app/auth/error/page.js +1 -1
  29. package/templates/base-project/apps/web/src/app/auth/forgot-password/page.js +1 -1
  30. package/templates/base-project/apps/web/src/app/auth/register/RegisterPageClient.js +1 -1
  31. package/templates/base-project/apps/web/src/app/auth/signin/SignInPageClient.js +1 -1
  32. package/templates/base-project/apps/web/src/app/layout.js +1 -1
  33. package/templates/base-project/apps/web/src/app/manifest.js +1 -1
  34. package/templates/base-project/apps/web/src/app/page.js +19 -19
  35. package/templates/base-project/apps/web/src/app/robots.js +1 -1
  36. package/templates/base-project/apps/web/src/app/sitemap.js +1 -1
  37. package/templates/base-project/apps/web/src/lib/analytics/umami-replay.js +1 -1
  38. package/templates/base-project/apps/web/src/lib/auth-middleware.js +1 -1
  39. package/templates/base-project/apps/web/src/lib/auth-signup.js +1 -1
  40. package/templates/base-project/apps/web/src/lib/auth.js +2 -2
  41. package/templates/base-project/apps/web/src/lib/jwt.js +1 -1
  42. package/templates/base-project/apps/web/src/lib/proxy-auth.js +1 -1
  43. package/templates/base-project/apps/web/src/lib/seo/site-metadata.js +1 -1
  44. package/templates/base-project/apps/web/src/preflight.js +3 -3
  45. package/templates/base-project/apps/web/src/proxy.js +1 -1
  46. package/templates/base-project/docs/START_HERE.md +2 -2
  47. package/templates/base-project/packages/db/package.json +2 -2
  48. package/templates/base-project/packages/db/src/client.js +3 -3
  49. package/templates/base-project/packages/db/src/umami.js +1 -1
  50. package/templates/base-project/scripts/check-loading.mjs +1 -1
  51. package/templates/base-project/scripts/doctor.js +1 -1
  52. package/templates/base-project/skills/add-endpoint/SKILL.md +1 -1
  53. package/templates/base-project/skills/ecommerce/SKILL.md +2 -2
  54. package/templates/base-project/skills/ecommerce-cart/SKILL.md +3 -3
  55. package/templates/base-project/skills/ecommerce-catalog/SKILL.md +3 -3
  56. package/templates/base-project/skills/ecommerce-checkout/SKILL.md +2 -2
  57. package/templates/base-project/skills/i18n/SKILL.md +6 -6
  58. package/templates/base-project/skills/payment/SKILL.md +8 -8
  59. package/templates/config/package.json +1 -1
  60. package/templates/config/src/app-url.js +1 -1
  61. package/templates/config/src/environment.js +1 -1
  62. package/templates/config/src/load-config.js +2 -2
  63. package/templates/config/src/redis.js +1 -1
  64. package/templates/config/src/validate-env.js +2 -2
  65. package/templates/jobs/README.md +2 -2
  66. package/templates/mobile/lib/errors.ts +1 -1
  67. package/templates/ui/src/theme-constants.js +1 -1
  68. package/templates/worker/README.md +2 -2
  69. package/templates/worker/package.json +4 -4
  70. package/templates/worker/src/handlers/email-job-validation.js +1 -1
  71. package/templates/worker/src/handlers/email.js +5 -5
  72. package/templates/worker/src/handlers/files.js +4 -4
  73. package/templates/worker/src/handlers/index.js +1 -1
  74. package/templates/worker/src/handlers/push-notification.js +3 -3
  75. package/templates/worker/src/index.js +6 -6
  76. package/templates/worker/src/lib/railway.js +2 -2
  77. package/templates/worker/src/lib/tokens.js +1 -1
  78. package/src/dependabot-config.test.js +0 -128
  79. package/src/deploy/adapters/railway.test.js +0 -318
  80. package/src/deploy/deploy.integration.test.js +0 -183
  81. package/src/deploy/deploy.test.js +0 -105
  82. package/src/deploy/discovery.test.js +0 -141
  83. package/src/mobile-template.test.js +0 -232
  84. package/src/prepare-hooks.test.js +0 -535
  85. package/src/scaffold-guards.test.js +0 -140
  86. package/src/scaffold-output.test.js +0 -228
  87. package/src/template-scripts.test.js +0 -160
  88. package/src/utils.test.js +0 -95
  89. package/src/worker-dockerfile.test.js +0 -85
@@ -17,7 +17,7 @@ let failed = false;
17
17
  function isDbBacked(pagePath) {
18
18
  const content = readFileSync(pagePath, "utf-8");
19
19
  // Matches scoped db packages in scaffolds (@scope/db) and the monorepo
20
- // package name (@techstream/quark-db).
20
+ // package name (@usequark/quark-db).
21
21
  return /@[^/"'\s]+\/(?:quark-)?db["']/.test(content);
22
22
  }
23
23
 
@@ -186,7 +186,7 @@ if (forgotPwContent && forgotPwContent.includes("quark-auth-layout")) {
186
186
  "imports",
187
187
  `Source files import "${importPattern}" but "${pkg}" is not installed`,
188
188
  badFiles.map((f) => ` ${path.relative(ROOT, f)}`).join("\n"),
189
- `Remove these imports or run: npx @techstream/quark-create-app add ${pkg}`,
189
+ `Remove these imports or run: npx @usequark/quark-create-app add ${pkg}`,
190
190
  );
191
191
  }
192
192
  }
@@ -11,7 +11,7 @@ Add a REST CRUD endpoint for an existing model: list/create on the collection ro
11
11
 
12
12
  - **API routes** live in `apps/web/src/app/api/<resource>/`.
13
13
  - **Data access** goes through query helpers in `packages/db/src/queries.js` — never call `prisma.*` directly.
14
- - **Auth** via `requireRole` from `@/lib/auth-middleware`; **validation** via Zod `validateBody`; **CSRF** via `withCsrfProtection` from `@techstream/quark-core`.
14
+ - **Auth** via `requireRole` from `@/lib/auth-middleware`; **validation** via Zod `validateBody`; **CSRF** via `withCsrfProtection` from `@usequark/quark-core`.
15
15
 
16
16
  ## Workflow
17
17
 
@@ -22,9 +22,9 @@ An ecommerce system manages a product catalog, shopping cart, checkout flow, ord
22
22
 
23
23
  - **Models** live in `packages/db/prisma/schema.prisma`. Every model needs `id`, `createdAt DateTime @default(now())`, `updatedAt DateTime @updatedAt`. After changes: `pnpm db:generate && pnpm db:migrate`.
24
24
  - **Data access** goes through query helpers in `packages/db/src/queries.js` — never call `prisma.*` directly in pages/actions.
25
- - **Server Actions** (preferred for mutations) use `"use server"`, Zod validation, and `AppError`/`ValidationError` from `@techstream/quark-core/errors`.
25
+ - **Server Actions** (preferred for mutations) use `"use server"`, Zod validation, and `AppError`/`ValidationError` from `@usequark/quark-core/errors`.
26
26
  - **Admin views** live under `apps/web/src/app/admin/` (see the admin-dashboard skill for product/order management).
27
- - **Auth** via `getCurrentSession` from `@techstream/quark-core`.
27
+ - **Auth** via `getCurrentSession` from `@usequark/quark-core`.
28
28
  - **Payment** integration follows the payment skill for Stripe Checkout or similar processors.
29
29
 
30
30
  ## Workflow
@@ -19,8 +19,8 @@ The cart is a temporary collection of items a user intends to purchase. Key conc
19
19
 
20
20
  - **Models** live in `packages/db/prisma/schema.prisma`. Every model needs `id`, `createdAt DateTime @default(now())`, `updatedAt DateTime @updatedAt`. After changes: `pnpm db:generate && pnpm db:migrate`.
21
21
  - **Data access** goes through query helpers in `packages/db/src/queries.js` — never call `prisma.*` directly in pages/actions.
22
- - **Server Actions** use `"use server"`, Zod validation, and `AppError`/`ValidationError` from `@techstream/quark-core/errors`.
23
- - **Auth** via `getCurrentSession` from `@techstream/quark-core`.
22
+ - **Server Actions** use `"use server"`, Zod validation, and `AppError`/`ValidationError` from `@usequark/quark-core/errors`.
23
+ - **Auth** via `getCurrentSession` from `@usequark/quark-core`.
24
24
 
25
25
  ## Models
26
26
 
@@ -88,7 +88,7 @@ Use a Prisma transaction to prevent race conditions. Check stock availability be
88
88
 
89
89
  ```js
90
90
  import { prisma } from "@__QUARK_SCOPE__/db";
91
- import { AppError } from "@techstream/quark-core/errors";
91
+ import { AppError } from "@usequark/quark-core/errors";
92
92
 
93
93
  export async function addToCart(cartId, variantId, quantity = 1) {
94
94
  return prisma.$transaction(async (tx) => {
@@ -20,7 +20,7 @@ The catalog is the foundation of an ecommerce system. It defines what you sell,
20
20
  - **Models** live in `packages/db/prisma/schema.prisma`. Every model needs `id`, `createdAt DateTime @default(now())`, `updatedAt DateTime @updatedAt`. After changes: `pnpm db:generate && pnpm db:migrate`.
21
21
  - **Data access** goes through query helpers in `packages/db/src/queries.js` — never call `prisma.*` directly in pages/actions.
22
22
  - **API routes** live in `apps/web/src/app/api/<resource>/`. Guard with `requireRole`, validate with Zod via `validateBody`, wrap mutations in `withCsrfProtection`. Follow `apps/web/src/app/api/users/route.js` as the reference shape.
23
- - **Server Actions** use `"use server"`, Zod validation, and `AppError`/`ValidationError` from `@techstream/quark-core/errors`.
23
+ - **Server Actions** use `"use server"`, Zod validation, and `AppError`/`ValidationError` from `@usequark/quark-core/errors`.
24
24
  - **Admin views** live under `apps/web/src/app/admin/products/` and `apps/web/src/app/admin/categories/`.
25
25
 
26
26
  ## Models
@@ -127,8 +127,8 @@ export async function getCategoryTree() {
127
127
  "use server";
128
128
  import { z } from "zod";
129
129
  import { prisma } from "@__QUARK_SCOPE__/db";
130
- import { ValidationError, AppError } from "@techstream/quark-core/errors";
131
- import { createLogger } from "@techstream/quark-core";
130
+ import { ValidationError, AppError } from "@usequark/quark-core/errors";
131
+ import { createLogger } from "@usequark/quark-core";
132
132
 
133
133
  const log = createLogger("action:product");
134
134
 
@@ -68,8 +68,8 @@ model OrderItem {
68
68
  "use server";
69
69
  import { z } from "zod";
70
70
  import { prisma } from "@__QUARK_SCOPE__/db";
71
- import { AppError, ValidationError } from "@techstream/quark-core/errors";
72
- import { createLogger } from "@techstream/quark-core";
71
+ import { AppError, ValidationError } from "@usequark/quark-core/errors";
72
+ import { createLogger } from "@usequark/quark-core";
73
73
 
74
74
  const log = createLogger("action:checkout");
75
75
 
@@ -34,8 +34,8 @@ A localized app must handle locale detection, routing, content translation, and
34
34
  - **Request config:** `getRequestConfig` from `next-intl/server` resolves the locale per request and loads message files.
35
35
  - **Models:** CMS models get a `locale String` field. Queries filter by locale with fallback chain.
36
36
  - **Validation** — Zod for all Server Actions and API routes. Use a locale enum for localized content submissions.
37
- - **Auth** via `getCurrentSession` from `@techstream/quark-core`.
38
- - **Locale utilities** from `@techstream/quark-core/locale`: `getDefaultLocale()`, `getSupportedLocales()`, `isLocaleSupported()`.
37
+ - **Auth** via `getCurrentSession` from `@usequark/quark-core`.
38
+ - **Locale utilities** from `@usequark/quark-core/locale`: `getDefaultLocale()`, `getSupportedLocales()`, `isLocaleSupported()`.
39
39
 
40
40
  ## Workflow
41
41
 
@@ -52,7 +52,7 @@ A localized app must handle locale detection, routing, content translation, and
52
52
  ```js
53
53
  // src/i18n/routing.js
54
54
  import { defineRouting } from "next-intl/routing";
55
- import { getDefaultLocale, getSupportedLocales } from "@techstream/quark-core/locale";
55
+ import { getDefaultLocale, getSupportedLocales } from "@usequark/quark-core/locale";
56
56
 
57
57
  const supportedLocales = getSupportedLocales();
58
58
 
@@ -104,7 +104,7 @@ export const config = {
104
104
  "use client";
105
105
  import { useLocale, useTranslations } from "next-intl";
106
106
  import { useRouter, usePathname } from "next/navigation";
107
- import { getSupportedLocales } from "@techstream/quark-core/locale";
107
+ import { getSupportedLocales } from "@usequark/quark-core/locale";
108
108
 
109
109
  export function LocaleSwitcher() {
110
110
  const locale = useLocale();
@@ -152,7 +152,7 @@ model Page {
152
152
  ## Example: locale-aware query
153
153
 
154
154
  ```js
155
- import { getDefaultLocale, isLocaleSupported } from "@techstream/quark-core/locale";
155
+ import { getDefaultLocale, isLocaleSupported } from "@usequark/quark-core/locale";
156
156
 
157
157
  export async function getPageBySlug(slug, locale) {
158
158
  const validLocale = isLocaleSupported(locale) ? locale : getDefaultLocale();
@@ -185,7 +185,7 @@ export async function generateMetadata({ params }) {
185
185
 
186
186
  ```js
187
187
  import { z } from "zod";
188
- import { isLocaleSupported } from "@techstream/quark-core/locale";
188
+ import { isLocaleSupported } from "@usequark/quark-core/locale";
189
189
 
190
190
  export const localizedPageSchema = z.object({
191
191
  title: z.string().min(1).max(255),
@@ -24,11 +24,11 @@ Key concepts:
24
24
 
25
25
  ## Framework context
26
26
 
27
- - **Stripe client** — `createStripeClient()` from `@techstream/quark-core/stripe`. Reads `STRIPE_SECRET_KEY` from env.
28
- - **Webhook route** — `apps/web/src/app/api/stripe/webhook/route.js`. Use `getStripeWebhookEvent()` from `@techstream/quark-core/stripe` to verify signatures.
27
+ - **Stripe client** — `createStripeClient()` from `@usequark/quark-core/stripe`. Reads `STRIPE_SECRET_KEY` from env.
28
+ - **Webhook route** — `apps/web/src/app/api/stripe/webhook/route.js`. Use `getStripeWebhookEvent()` from `@usequark/quark-core/stripe` to verify signatures.
29
29
  - **Validation** — Zod for all incoming data. Webhook event data is already validated by Stripe's SDK.
30
- - **Errors** — `AppError` / `ValidationError` from `@techstream/quark-core/errors` for app errors. Never throw on webhook failures — return 200 to prevent Stripe retries for unfixable errors.
31
- - **Logging** — `createLogger("stripe:webhook")` from `@techstream/quark-core`.
30
+ - **Errors** — `AppError` / `ValidationError` from `@usequark/quark-core/errors` for app errors. Never throw on webhook failures — return 200 to prevent Stripe retries for unfixable errors.
31
+ - **Logging** — `createLogger("stripe:webhook")` from `@usequark/quark-core`.
32
32
  - **Models** — add `stripeCustomerId String?` to User, `stripeSessionId String?` / `stripeSubscriptionId String?` to relevant models. Every model needs `createdAt` / `updatedAt`.
33
33
 
34
34
  ## Checkout sessions
@@ -49,7 +49,7 @@ export const checkoutSchema = z.object({
49
49
  ### One-time payment
50
50
 
51
51
  ```js
52
- import { createStripeClient } from "@techstream/quark-core/stripe";
52
+ import { createStripeClient } from "@usequark/quark-core/stripe";
53
53
 
54
54
  const stripe = await createStripeClient();
55
55
  const session = await stripe.checkout.sessions.create({
@@ -82,8 +82,8 @@ const session = await stripe.checkout.sessions.create({
82
82
  ```js
83
83
  // apps/web/src/app/api/stripe/webhook/route.js
84
84
  import { NextResponse } from "next/server";
85
- import { getStripeWebhookEvent } from "@techstream/quark-core/stripe";
86
- import { createLogger } from "@techstream/quark-core";
85
+ import { getStripeWebhookEvent } from "@usequark/quark-core/stripe";
86
+ import { createLogger } from "@usequark/quark-core";
87
87
  import { prisma } from "@__QUARK_SCOPE__/db";
88
88
 
89
89
  const log = createLogger("stripe:webhook");
@@ -180,7 +180,7 @@ model WebhookEvent {
180
180
  ### Create or retrieve Stripe customer
181
181
 
182
182
  ```js
183
- import { createStripeClient } from "@techstream/quark-core/stripe";
183
+ import { createStripeClient } from "@usequark/quark-core/stripe";
184
184
 
185
185
  export async function getOrCreateStripeCustomer(user) {
186
186
  if (user.stripeCustomerId) return user.stripeCustomerId;
@@ -13,7 +13,7 @@
13
13
  "./redis": "./src/redis.js"
14
14
  },
15
15
  "dependencies": {
16
- "@techstream/quark-core": "^2.0.0",
16
+ "@usequark/quark-core": "^2.0.0",
17
17
  "ioredis": "^6.0.0",
18
18
  "zod": "^4.6.5"
19
19
  }
@@ -20,7 +20,7 @@
20
20
  * listed in ALLOWED_ORIGINS (comma-separated).
21
21
  */
22
22
 
23
- import { ValidationError } from "@techstream/quark-core/errors";
23
+ import { ValidationError } from "@usequark/quark-core/errors";
24
24
 
25
25
  /**
26
26
  * Resolves the canonical application URL.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @techstream/quark-config - Environment Configuration
2
+ * @usequark/quark-config - Environment Configuration
3
3
  * Provides environment-specific defaults for dev, test, staging, and production.
4
4
  * Each environment defines sensible defaults that can be overridden via env vars.
5
5
  */
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @techstream/quark-config - Configuration Loader
2
+ * @usequark/quark-config - Configuration Loader
3
3
  * Centralised configuration management that combines environment validation,
4
4
  * environment-specific defaults, and user overrides into a single config object.
5
5
  *
6
6
  * Usage:
7
- * import { loadConfig } from "@techstream/quark-config";
7
+ * import { loadConfig } from "@usequark/quark-config";
8
8
  * const config = loadConfig(); // validates env + returns typed config
9
9
  * const config = loadConfig({ cache: { defaultTtl: 120 } }); // with overrides
10
10
  */
@@ -1,4 +1,4 @@
1
- import { resolveRedisConnection } from "@techstream/quark-core";
1
+ import { resolveRedisConnection } from "@usequark/quark-core";
2
2
 
3
3
  let _redis = null;
4
4
 
@@ -1,5 +1,5 @@
1
- import { createLogger } from "@techstream/quark-core";
2
- import { ValidationError } from "@techstream/quark-core/errors";
1
+ import { createLogger } from "@usequark/quark-core";
2
+ import { ValidationError } from "@usequark/quark-core/errors";
3
3
  import { z } from "zod";
4
4
  import { syncNextAuthUrl } from "./app-url.js";
5
5
 
@@ -41,11 +41,11 @@ Treat them as examples, not a required domain model.
41
41
  1. Add a queue or job name in `src/definitions.js`
42
42
  2. Create a handler in `apps/worker/src/handlers/`
43
43
  3. Register that handler in `apps/worker/src/handlers/index.js`
44
- 4. Dispatch the job from the web app using `createQueue()` and `addJob()` from `@techstream/quark-core`
44
+ 4. Dispatch the job from the web app using `createQueue()` and `addJob()` from `@usequark/quark-core`
45
45
 
46
46
  ## Relationship to Quark Core
47
47
 
48
- `@techstream/quark-core` provides the queue infrastructure.
48
+ `@usequark/quark-core` provides the queue infrastructure.
49
49
 
50
50
  `@yourscope/jobs` defines **your** queue names and job names.
51
51
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Mobile equivalent of @techstream/quark-core's AppError.
2
+ * Mobile equivalent of @usequark/quark-core's AppError.
3
3
  *
4
4
  * React Native cannot import Node.js packages, so this module defines a
5
5
  * client-side error class whose shape mirrors AppError.toJSON() — same
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Theme system constants for @techstream/quark-ui.
2
+ * Theme system constants for @usequark/quark-ui.
3
3
  *
4
4
  * These three values form the contract between ThemeProvider and any
5
5
  * out-of-tree component (e.g. HomeThemeToggle in apps/web) that interoperates
@@ -16,7 +16,7 @@ pnpm dev # Starts worker with file watching
16
16
  2. Create a handler in `apps/worker/src/handlers/<job-name>.js`:
17
17
 
18
18
  ```javascript
19
- import { createLogger } from "@techstream/quark-core";
19
+ import { createLogger } from "@usequark/quark-core";
20
20
 
21
21
  const log = createLogger("job:my-task");
22
22
 
@@ -39,7 +39,7 @@ const jobHandlers = {
39
39
  ## Dispatching Jobs
40
40
 
41
41
  ```javascript
42
- import { createQueue, addJob } from "@techstream/quark-core";
42
+ import { createQueue, addJob } from "@usequark/quark-core";
43
43
  import { JOB_NAMES } from "@yourscope/jobs";
44
44
 
45
45
  const queue = createQueue("default");
@@ -22,10 +22,10 @@
22
22
  "license": "MIT",
23
23
  "packageManager": "pnpm@10.12.1",
24
24
  "dependencies": {
25
- "@techstream/quark-config": "workspace:*",
26
- "@techstream/quark-core": "^2.0.0",
27
- "@techstream/quark-db": "workspace:*",
28
- "@techstream/quark-jobs": "workspace:*",
25
+ "@usequark/quark-config": "workspace:*",
26
+ "@usequark/quark-core": "^2.0.0",
27
+ "@usequark/quark-db": "workspace:*",
28
+ "@usequark/quark-jobs": "workspace:*",
29
29
  "bullmq": "^6.3.8",
30
30
  "jose": "^6.2.12"
31
31
  },
@@ -1,4 +1,4 @@
1
- import { AppError, ValidationError } from "@techstream/quark-core/errors";
1
+ import { AppError, ValidationError } from "@usequark/quark-core/errors";
2
2
 
3
3
  export function requireWelcomeEmailUserId(data) {
4
4
  const userId = data?.userId;
@@ -7,9 +7,9 @@ import {
7
7
  createEmailService,
8
8
  passwordResetEmail,
9
9
  welcomeEmail,
10
- } from "@techstream/quark-core";
11
- import { prisma } from "@techstream/quark-db";
12
- import { JOB_NAMES } from "@techstream/quark-jobs";
10
+ } from "@usequark/quark-core";
11
+ import { prisma } from "@usequark/quark-db";
12
+ import { JOB_NAMES } from "@usequark/quark-jobs";
13
13
  import {
14
14
  requireResetPasswordEmailData,
15
15
  requireUserEmailRecord,
@@ -21,7 +21,7 @@ const emailService = createEmailService();
21
21
  /**
22
22
  * Job handler for SEND_WELCOME_EMAIL
23
23
  * @param {import("bullmq").Job} bullJob
24
- * @param {import("@techstream/quark-core").Logger} logger
24
+ * @param {import("@usequark/quark-core").Logger} logger
25
25
  */
26
26
  export async function handleSendWelcomeEmail(bullJob, logger) {
27
27
  const userId = requireWelcomeEmailUserId(bullJob.data);
@@ -60,7 +60,7 @@ export async function handleSendWelcomeEmail(bullJob, logger) {
60
60
  /**
61
61
  * Job handler for SEND_RESET_PASSWORD_EMAIL
62
62
  * @param {import("bullmq").Job} bullJob
63
- * @param {import("@techstream/quark-core").Logger} logger
63
+ * @param {import("@usequark/quark-core").Logger} logger
64
64
  */
65
65
  export async function handleSendResetPasswordEmail(bullJob, logger) {
66
66
  const { userId, resetUrl } = requireResetPasswordEmailData(bullJob.data);
@@ -3,16 +3,16 @@
3
3
  * Processes file-related background jobs (cleanup, etc.)
4
4
  */
5
5
 
6
- import { createStorage } from "@techstream/quark-core";
7
- import { file } from "@techstream/quark-db";
8
- import { JOB_NAMES } from "@techstream/quark-jobs";
6
+ import { createStorage } from "@usequark/quark-core";
7
+ import { file } from "@usequark/quark-db";
8
+ import { JOB_NAMES } from "@usequark/quark-jobs";
9
9
 
10
10
  /**
11
11
  * Job handler for CLEANUP_ORPHANED_FILES
12
12
  * Deletes files with no owner that are older than a retention period.
13
13
  *
14
14
  * @param {import("bullmq").Job} bullJob
15
- * @param {import("@techstream/quark-core").Logger} logger
15
+ * @param {import("@usequark/quark-core").Logger} logger
16
16
  */
17
17
  export async function handleCleanupOrphanedFiles(bullJob, logger) {
18
18
  const retentionHours = bullJob.data?.retentionHours || 24;
@@ -4,7 +4,7 @@
4
4
  * Each handler receives (bullJob, logger) and returns a result object.
5
5
  */
6
6
 
7
- import { JOB_NAMES } from "@techstream/quark-jobs";
7
+ import { JOB_NAMES } from "@usequark/quark-jobs";
8
8
  import {
9
9
  handleSendResetPasswordEmail,
10
10
  handleSendWelcomeEmail,
@@ -4,8 +4,8 @@
4
4
  * No Firebase SDK — uses HTTP APIs with service account credentials from env.
5
5
  */
6
6
 
7
- import { AppError, ValidationError } from "@techstream/quark-core/errors";
8
- import { prisma } from "@techstream/quark-db";
7
+ import { AppError, ValidationError } from "@usequark/quark-core/errors";
8
+ import { prisma } from "@usequark/quark-db";
9
9
  import { importPKCS8, SignJWT } from "jose";
10
10
 
11
11
  const APNS_KEY = process.env.APNS_KEY;
@@ -19,7 +19,7 @@ const GCP_SERVICE_ACCOUNT = process.env.GCP_SERVICE_ACCOUNT;
19
19
  /**
20
20
  * Job handler for SEND_PUSH_NOTIFICATION
21
21
  * @param {import("bullmq").Job} bullJob
22
- * @param {import("@techstream/quark-core").Logger} logger
22
+ * @param {import("@usequark/quark-core").Logger} logger
23
23
  */
24
24
  export async function handleSendPushNotification(bullJob, logger) {
25
25
  const { userId, title, body: notificationBody, data } = bullJob.data;
@@ -11,10 +11,10 @@ import {
11
11
  createWorker,
12
12
  getRedisUrl,
13
13
  updateQueueDepths,
14
- } from "@techstream/quark-core";
15
- import { AppError } from "@techstream/quark-core/errors";
16
- import { job, prisma } from "@techstream/quark-db";
17
- import { JOB_NAMES, JOB_QUEUES } from "@techstream/quark-jobs";
14
+ } from "@usequark/quark-core";
15
+ import { AppError } from "@usequark/quark-core/errors";
16
+ import { job, prisma } from "@usequark/quark-db";
17
+ import { JOB_NAMES, JOB_QUEUES } from "@usequark/quark-jobs";
18
18
  import { jobHandlers } from "./handlers/index.js";
19
19
 
20
20
  const logger = createLogger("worker");
@@ -242,7 +242,7 @@ export async function waitForDatabase(
242
242
  */
243
243
  async function preflight() {
244
244
  // Load and validate environment variables
245
- const { loadEnv } = await import("@techstream/quark-config");
245
+ const { loadEnv } = await import("@usequark/quark-config");
246
246
  loadEnv("worker");
247
247
 
248
248
  logger.info("Running preflight health checks");
@@ -362,7 +362,7 @@ async function createQueueWorker(queueName) {
362
362
  */
363
363
  async function startWorker() {
364
364
  // Load and validate environment variables
365
- const { loadEnv } = await import("@techstream/quark-config");
365
+ const { loadEnv } = await import("@usequark/quark-config");
366
366
  loadEnv("worker");
367
367
 
368
368
  logger.info("Starting Quark Worker Service");
@@ -3,8 +3,8 @@
3
3
  * Fetches estimated usage and deployment data from Railway's GraphQL API.
4
4
  */
5
5
 
6
- import { createLogger } from "@techstream/quark-core";
7
- import { AppError } from "@techstream/quark-core/errors";
6
+ import { createLogger } from "@usequark/quark-core";
7
+ import { AppError } from "@usequark/quark-core/errors";
8
8
 
9
9
  const log = createLogger("lib:railway");
10
10
 
@@ -1,4 +1,4 @@
1
- import { createLogger } from "@techstream/quark-core";
1
+ import { createLogger } from "@usequark/quark-core";
2
2
 
3
3
  const _logger = createLogger("worker:tokens");
4
4
 
@@ -1,128 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Guard the scaffold template's dependabot config.
5
- *
6
- * The template used to group by `dependency-type` alone, which produced one
7
- * PR bundling patch, minor and major bumps together. That is how several
8
- * breaking changes reached this repo unnoticed - bullmq 6 removed
9
- * `queue.client` and shipped two silent production regressions inside a
10
- * 35-package diff.
11
- *
12
- * This checks the shipped template still separates majors, so a scaffolded
13
- * project does not inherit the problem.
14
- *
15
- * Run with: node --test packages/cli/src/dependabot-config.test.js
16
- */
17
-
18
- import assert from "node:assert/strict";
19
- import fs from "node:fs";
20
- import path from "node:path";
21
- import { describe, it } from "node:test";
22
- import { fileURLToPath } from "node:url";
23
-
24
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
25
- const REPO_ROOT = path.resolve(__dirname, "../../..");
26
-
27
- const CONFIGS = [
28
- ["monorepo", ".github/dependabot.yml"],
29
- [
30
- "scaffold template",
31
- "packages/cli/templates/base-project/.github/dependabot.yml",
32
- ],
33
- ];
34
-
35
- function readConfig(relativePath) {
36
- return fs.readFileSync(path.join(REPO_ROOT, relativePath), "utf8");
37
- }
38
-
39
- describe("dependabot config", () => {
40
- for (const [label, relativePath] of CONFIGS) {
41
- it(`${label} isolates major bumps into their own group`, () => {
42
- const text = readConfig(relativePath);
43
-
44
- assert.match(
45
- text,
46
- /production-majors:[\s\S]*?dependency-type:\s*production[\s\S]*?update-types:\s*\["major"\]/,
47
- "production majors must be grouped separately so a breaking change is reviewed alone",
48
- );
49
- assert.match(
50
- text,
51
- /development-majors:[\s\S]*?dependency-type:\s*development[\s\S]*?update-types:\s*\["major"\]/,
52
- "development majors must be grouped separately too",
53
- );
54
- });
55
-
56
- it(`${label} does not lump every production bump into one group`, () => {
57
- const text = readConfig(relativePath);
58
-
59
- // A bare `production:` group with no update-types collects majors,
60
- // minors and patches into a single reviewable-looking PR.
61
- assert.doesNotMatch(
62
- text,
63
- /\n {6}production:\n {8}dependency-type:\s*production\n/,
64
- "a catch-all production group re-creates the 35-package PR problem",
65
- );
66
- });
67
-
68
- it(`${label} keeps a PR limit that can hold the extra groups`, () => {
69
- const text = readConfig(relativePath);
70
- const limit = Number(
71
- (text.match(/open-pull-requests-limit:\s*(\d+)/) || [])[1],
72
- );
73
-
74
- assert.ok(
75
- Number.isInteger(limit) && limit >= 6,
76
- `open-pull-requests-limit should be at least 6 for the split groups (got ${limit})`,
77
- );
78
- });
79
- }
80
- });
81
-
82
- /**
83
- * The auto-merge workflow is the other half of the split, and the only part
84
- * that actually merges anything.
85
- *
86
- * Splitting dependabot into per-severity groups changes what a human sees. It
87
- * does not change what merges unattended - that is gated solely by
88
- * `update-type == 'version-update:semver-patch'`. A dependency that ships a
89
- * breaking change in a *patch* passes straight through, and that is exactly how
90
- * bullmq 6's `queue.client` removal reached this repo. Majors already need a
91
- * human by virtue of not matching; this test keeps it that way.
92
- *
93
- * The monorepo runs this workflow; the template ships an equivalent one, so a
94
- * scaffolded project inherits the same gate.
95
- */
96
- const AUTO_MERGE_WORKFLOWS = [
97
- ["monorepo", ".github/workflows/dependabot-auto-merge.yml"],
98
- [
99
- "scaffold template",
100
- "packages/cli/templates/base-project/.github/workflows/dependabot-auto-merge.yml",
101
- ],
102
- ];
103
-
104
- describe("dependabot auto-merge gate", () => {
105
- for (const [label, relativePath] of AUTO_MERGE_WORKFLOWS) {
106
- it(`${label} gates auto-merge on the semver update type`, () => {
107
- const text = readConfig(relativePath);
108
-
109
- assert.match(
110
- text,
111
- /version-update:semver-patch/,
112
- "the auto-merge gate must key on the semver patch update type, so minors and majors still need a human",
113
- );
114
- });
115
-
116
- it(`${label} does not merge every dependabot update`, () => {
117
- const text = readConfig(relativePath);
118
-
119
- // An unconditional `gh pr merge` would auto-merge majors unattended,
120
- // which is precisely how the bullmq break nearly landed.
121
- assert.doesNotMatch(
122
- text,
123
- /if:\s*github\.actor\s*==\s*'dependabot\[bot\]'\n\s*steps:/,
124
- "auto-merge must be gated on the update type, not just the actor",
125
- );
126
- });
127
- }
128
- });