@techstream/quark-create-app 1.5.3 → 1.6.0

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 (48) hide show
  1. package/package.json +4 -2
  2. package/src/index.js +52 -9
  3. package/templates/base-project/.github/dependabot.yml +12 -0
  4. package/templates/base-project/.github/workflows/ci.yml +97 -0
  5. package/templates/base-project/.github/workflows/dependabot-auto-merge.yml +22 -0
  6. package/templates/base-project/.github/workflows/release.yml +38 -0
  7. package/templates/base-project/apps/web/biome.json +7 -0
  8. package/templates/base-project/apps/web/jsconfig.json +5 -5
  9. package/templates/base-project/apps/web/next.config.js +86 -1
  10. package/templates/base-project/apps/web/package.json +4 -4
  11. package/templates/base-project/apps/web/src/app/api/auth/register/route.js +6 -7
  12. package/templates/base-project/apps/web/src/app/layout.js +3 -4
  13. package/templates/base-project/apps/web/src/app/manifest.js +12 -0
  14. package/templates/base-project/apps/web/src/app/robots.js +21 -0
  15. package/templates/base-project/apps/web/src/app/sitemap.js +20 -0
  16. package/templates/base-project/apps/web/src/lib/seo/indexing.js +23 -0
  17. package/templates/base-project/apps/web/src/lib/seo/site-metadata.js +33 -0
  18. package/templates/base-project/apps/web/src/proxy.js +1 -2
  19. package/templates/base-project/apps/worker/package.json +4 -4
  20. package/templates/base-project/apps/worker/src/index.js +26 -12
  21. package/templates/base-project/apps/worker/src/index.test.js +296 -15
  22. package/templates/base-project/biome.json +44 -0
  23. package/templates/base-project/docker-compose.yml +7 -4
  24. package/templates/base-project/package.json +1 -1
  25. package/templates/base-project/packages/db/package.json +1 -1
  26. package/templates/base-project/packages/db/prisma/schema.prisma +1 -17
  27. package/templates/base-project/packages/db/prisma.config.ts +3 -2
  28. package/templates/base-project/packages/db/scripts/seed.js +117 -30
  29. package/templates/base-project/packages/db/src/queries.js +52 -118
  30. package/templates/base-project/packages/db/src/queries.test.js +0 -29
  31. package/templates/base-project/packages/db/src/schemas.js +0 -12
  32. package/templates/base-project/pnpm-workspace.yaml +4 -0
  33. package/templates/base-project/turbo.json +5 -3
  34. package/templates/config/package.json +2 -0
  35. package/templates/config/src/environment.js +270 -0
  36. package/templates/config/src/index.js +10 -18
  37. package/templates/config/src/load-config.js +135 -0
  38. package/templates/config/src/validate-env.js +60 -2
  39. package/templates/jobs/package.json +2 -2
  40. package/templates/jobs/src/definitions.test.js +34 -0
  41. package/templates/jobs/src/index.js +1 -1
  42. package/templates/ui/package.json +4 -4
  43. package/templates/ui/src/button.test.js +23 -0
  44. package/templates/ui/src/index.js +1 -3
  45. package/templates/base-project/apps/web/src/app/api/posts/[id]/route.js +0 -65
  46. package/templates/base-project/apps/web/src/app/api/posts/route.js +0 -95
  47. package/templates/ui/src/card.js +0 -14
  48. package/templates/ui/src/input.js +0 -11
@@ -1,95 +0,0 @@
1
- import {
2
- createQueryBuilder,
3
- validateBody,
4
- withCsrfProtection,
5
- } from "@techstream/quark-core";
6
- import { post, postCreateSchema } from "@techstream/quark-db";
7
- import { NextResponse } from "next/server";
8
- import { z } from "zod";
9
- import { requireAuth } from "@/lib/auth-middleware";
10
- import { handleError } from "../error-handler";
11
-
12
- const paginationSchema = z.object({
13
- page: z.coerce.number().int().min(1).default(1),
14
- limit: z.coerce.number().int().min(1).max(100).default(10),
15
- });
16
-
17
- const querySchema = paginationSchema.extend({
18
- search: z.string().optional(),
19
- status: z.enum(["draft", "published"]).optional(),
20
- authorId: z.string().optional(),
21
- sort: z.enum(["createdAt", "updatedAt", "title"]).optional(),
22
- order: z.enum(["asc", "desc"]).default("desc"),
23
- });
24
-
25
- export async function GET(request) {
26
- try {
27
- const { searchParams } = new URL(request.url);
28
- const { page, limit, search, status, authorId, sort, order } =
29
- querySchema.parse({
30
- page: searchParams.get("page") ?? undefined,
31
- limit: searchParams.get("limit") ?? undefined,
32
- search: searchParams.get("search") ?? undefined,
33
- status: searchParams.get("status") ?? undefined,
34
- authorId: searchParams.get("authorId") ?? undefined,
35
- sort: searchParams.get("sort") ?? undefined,
36
- order: searchParams.get("order") ?? undefined,
37
- });
38
-
39
- const skip = (page - 1) * limit;
40
-
41
- // Build query with filters, search, and sort
42
- const qb = createQueryBuilder({
43
- filterableFields: ["published", "authorId"],
44
- searchFields: ["title", "content"],
45
- sortableFields: ["createdAt", "updatedAt", "title"],
46
- });
47
-
48
- // Apply filters
49
- if (status === "published") {
50
- qb.filter("published", "eq", true);
51
- } else if (status === "draft") {
52
- qb.filter("published", "eq", false);
53
- }
54
-
55
- if (authorId) {
56
- qb.filter("authorId", "eq", authorId);
57
- }
58
-
59
- // Apply search
60
- if (search) {
61
- qb.search(search);
62
- }
63
-
64
- // Apply sort
65
- if (sort) {
66
- qb.sort(sort, order);
67
- }
68
-
69
- const posts = await post.findAll({
70
- skip,
71
- take: limit,
72
- where: qb.toWhere(),
73
- orderBy: qb.toOrderBy(),
74
- });
75
-
76
- return NextResponse.json(posts);
77
- } catch (error) {
78
- return handleError(error);
79
- }
80
- }
81
-
82
- export const POST = withCsrfProtection(async (request) => {
83
- try {
84
- const session = await requireAuth();
85
- const data = await validateBody(request, postCreateSchema);
86
-
87
- const newPost = await post.create({
88
- ...data,
89
- authorId: session.user.id,
90
- });
91
- return NextResponse.json(newPost, { status: 201 });
92
- } catch (error) {
93
- return handleError(error);
94
- }
95
- });
@@ -1,14 +0,0 @@
1
- import React from "react";
2
-
3
- export const Card = ({ className, children, ...props }) => {
4
- const baseStyles = "bg-white rounded-lg shadow-md p-4";
5
-
6
- return React.createElement(
7
- "div",
8
- {
9
- className: `${baseStyles} ${className || ""}`,
10
- ...props,
11
- },
12
- children,
13
- );
14
- };
@@ -1,11 +0,0 @@
1
- import React from "react";
2
-
3
- export const Input = ({ className, ...props }) => {
4
- const baseStyles =
5
- "px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500";
6
-
7
- return React.createElement("input", {
8
- className: `${baseStyles} ${className || ""}`,
9
- ...props,
10
- });
11
- };