create-m5kdev 0.16.4 → 0.16.5

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 (22) hide show
  1. package/package.json +1 -1
  2. package/templates/minimal-app/README.md.tpl +2 -2
  3. package/templates/minimal-app/apps/server/drizzle/generate-schema.ts.tpl +33 -33
  4. package/templates/minimal-app/apps/server/drizzle/sync.ts.tpl +9 -9
  5. package/templates/minimal-app/apps/server/drizzle.config.ts.tpl +3 -3
  6. package/templates/minimal-app/apps/server/package.json.tpl +9 -9
  7. package/templates/minimal-app/apps/server/src/app.ts.tpl +95 -95
  8. package/templates/minimal-app/apps/server/src/db.ts.tpl +7 -7
  9. package/templates/minimal-app/apps/server/src/index.ts.tpl +34 -34
  10. package/templates/minimal-app/apps/server/src/lib/auth.ts.tpl +6 -6
  11. package/templates/minimal-app/apps/server/src/modules/posts/posts.db.ts.tpl +45 -45
  12. package/templates/minimal-app/apps/server/src/modules/posts/posts.module.ts.tpl +37 -37
  13. package/templates/minimal-app/apps/server/src/modules/posts/posts.repository.ts.tpl +22 -22
  14. package/templates/minimal-app/apps/server/src/modules/posts/posts.service.ts.tpl +146 -146
  15. package/templates/minimal-app/apps/server/src/modules/posts/posts.trpc.ts.tpl +41 -41
  16. package/templates/minimal-app/apps/server/src/modules.ts.tpl +37 -37
  17. package/templates/minimal-app/apps/server/src/repository.ts.tpl +6 -6
  18. package/templates/minimal-app/apps/server/src/schema-modules.ts.tpl +14 -14
  19. package/templates/minimal-app/apps/server/src/service.ts.tpl +7 -7
  20. package/templates/minimal-app/apps/server/src/trpc.ts.tpl +6 -6
  21. package/templates/minimal-app/apps/server/src/utils/trpc.ts.tpl +8 -8
  22. package/templates/minimal-app/apps/server/src/workflow.ts.tpl +4 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-m5kdev",
3
- "version": "0.16.4",
3
+ "version": "0.16.5",
4
4
  "license": "GPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,8 +18,8 @@ pnpm --filter ./apps/server seed
18
18
  pnpm dev
19
19
  ```
20
20
 
21
- The starter uses a local LibSQL file by default and writes local auth emails to `apps/server/.emails`.
22
- Before running `drizzle-kit`, the starter generates `apps/server/src/generated/schema.ts` from the registered backend modules.
21
+ The starter uses a local LibSQL file by default and writes local auth emails to `apps/server/.emails`.
22
+ Before running `drizzle-kit`, the starter generates `apps/server/src/generated/schema.ts` from the registered backend modules.
23
23
 
24
24
  ## Demo Credentials
25
25
 
@@ -1,33 +1,33 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
3
- import { collectBackendSchema, generateBackendSchemaSource } from "@m5kdev/backend/app";
4
- import { backendSchemaModules } from "../src/schema-modules";
5
-
6
- export async function generateSchema(): Promise<void> {
7
- const collected = collectBackendSchema(backendSchemaModules, {
8
- env: process.env,
9
- });
10
- const outputDirectory = path.resolve(process.cwd(), "src/generated");
11
- const outputPath = path.join(outputDirectory, "schema.ts");
12
-
13
- const source = [
14
- 'import { collectBackendSchema } from "@m5kdev/backend/app";',
15
- 'import { backendSchemaModules } from "../schema-modules";',
16
- "",
17
- "const collected = collectBackendSchema(backendSchemaModules, {",
18
- " env: process.env,",
19
- "});",
20
- "",
21
- generateBackendSchemaSource({
22
- schema: collected.schema,
23
- schemaExpression: "collected.schema",
24
- }),
25
- ].join("\n");
26
-
27
- await fs.mkdir(outputDirectory, { recursive: true });
28
- await fs.writeFile(outputPath, source, "utf8");
29
-
30
- console.info(`Generated Drizzle schema at ${outputPath}`);
31
- }
32
-
33
- void generateSchema();
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { collectBackendSchema, generateBackendSchemaSource } from "@m5kdev/backend/app";
4
+ import { backendSchemaModules } from "../src/schema-modules";
5
+
6
+ export async function generateSchema(): Promise<void> {
7
+ const collected = collectBackendSchema(backendSchemaModules, {
8
+ env: process.env,
9
+ });
10
+ const outputDirectory = path.resolve(process.cwd(), "src/generated");
11
+ const outputPath = path.join(outputDirectory, "schema.ts");
12
+
13
+ const source = [
14
+ 'import { collectBackendSchema } from "@m5kdev/backend/app";',
15
+ 'import { backendSchemaModules } from "../schema-modules";',
16
+ "",
17
+ "const collected = collectBackendSchema(backendSchemaModules, {",
18
+ " env: process.env,",
19
+ "});",
20
+ "",
21
+ generateBackendSchemaSource({
22
+ schema: collected.schema,
23
+ schemaExpression: "collected.schema",
24
+ }),
25
+ ].join("\n");
26
+
27
+ await fs.mkdir(outputDirectory, { recursive: true });
28
+ await fs.writeFile(outputPath, source, "utf8");
29
+
30
+ console.info(`Generated Drizzle schema at ${outputPath}`);
31
+ }
32
+
33
+ void generateSchema();
@@ -1,12 +1,12 @@
1
- import { spawnSync } from "node:child_process";
2
- import { generateSchema } from "./generate-schema";
3
-
4
- export async function syncDatabase(): Promise<void> {
5
- await generateSchema();
6
-
7
- const command = process.platform === "win32" ? "drizzle-kit.cmd" : "drizzle-kit";
8
- const result = spawnSync(command, ["push", "--config", "drizzle.config.ts", "--force"], {
9
- cwd: process.cwd(),
1
+ import { spawnSync } from "node:child_process";
2
+ import { generateSchema } from "./generate-schema";
3
+
4
+ export async function syncDatabase(): Promise<void> {
5
+ await generateSchema();
6
+
7
+ const command = process.platform === "win32" ? "drizzle-kit.cmd" : "drizzle-kit";
8
+ const result = spawnSync(command, ["push", "--config", "drizzle.config.ts", "--force"], {
9
+ cwd: process.cwd(),
10
10
  env: process.env,
11
11
  stdio: "inherit",
12
12
  });
@@ -3,9 +3,9 @@ import { defineConfig } from "drizzle-kit";
3
3
 
4
4
  dotenv.config({ path: "../shared/.env" });
5
5
 
6
- const url = process.env.TURSO_DATABASE_URL || process.env.DATABASE_URL;
7
- const authToken = process.env.TURSO_AUTH_TOKEN;
8
- const schema = "./src/generated/schema.ts";
6
+ const url = process.env.TURSO_DATABASE_URL || process.env.DATABASE_URL;
7
+ const authToken = process.env.TURSO_AUTH_TOKEN;
8
+ const schema = "./src/generated/schema.ts";
9
9
 
10
10
  if (!url) {
11
11
  throw new Error("DATABASE_URL or TURSO_DATABASE_URL must be set");
@@ -5,15 +5,15 @@
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
7
7
  "dev": "tsx watch --env-file=../shared/.env src/index.ts",
8
- "build": "tsup",
9
- "start": "node dist/index.js",
10
- "lint": "biome check .",
11
- "lint:fix": "biome check . --write",
12
- "check-types": "tsc --noEmit",
13
- "generate:schema": "tsx --env-file=../shared/.env drizzle/generate-schema.ts",
14
- "sync": "tsx --env-file=../shared/.env drizzle/sync.ts",
15
- "seed": "tsx --env-file=../shared/.env drizzle/seed.ts"
16
- },
8
+ "build": "tsup",
9
+ "start": "node dist/index.js",
10
+ "lint": "biome check .",
11
+ "lint:fix": "biome check . --write",
12
+ "check-types": "tsc --noEmit",
13
+ "generate:schema": "tsx --env-file=../shared/.env drizzle/generate-schema.ts",
14
+ "sync": "tsx --env-file=../shared/.env drizzle/sync.ts",
15
+ "seed": "tsx --env-file=../shared/.env drizzle/seed.ts"
16
+ },
17
17
  "dependencies": {
18
18
  "{{PACKAGE_SCOPE}}/email": "workspace:*",
19
19
  "{{PACKAGE_SCOPE}}/shared": "workspace:*",
@@ -1,95 +1,95 @@
1
- import { createBackendApp, type InferBackendAppRouter } from "@m5kdev/backend/app";
2
- import { createBetterAuth } from "@m5kdev/backend/modules/auth/auth.lib";
3
- import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
4
- import cors from "cors";
5
- import express from "express";
6
- import {
7
- authBackendModule,
8
- emailBackendModule,
9
- notificationBackendModule,
10
- postsBackendModule,
11
- workflowBackendModule,
12
- } from "./modules";
13
-
14
- const app = express();
15
- const appUrl = process.env.VITE_APP_URL ?? "http://localhost:5173";
16
- const serverUrl = process.env.VITE_SERVER_URL ?? "http://localhost:8080";
17
-
18
- app.use(express.json());
19
- app.use(
20
- cors({
21
- origin: [appUrl],
22
- credentials: true,
23
- methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
24
- allowedHeaders: ["Content-Type", "Authorization"],
25
- })
26
- );
27
-
28
- const databaseUrl = process.env.DATABASE_URL ?? "file:./local.db";
29
- const syncUrl = process.env.TURSO_DATABASE_URL;
30
- const authToken = process.env.TURSO_AUTH_TOKEN;
31
- const redisUrl = process.env.REDIS_URL ?? "redis://127.0.0.1:6379";
32
- const resendApiKey = process.env.RESEND_API_KEY;
33
-
34
- const connection =
35
- syncUrl && authToken
36
- ? {
37
- url: databaseUrl,
38
- syncUrl,
39
- authToken,
40
- syncInterval: 60,
41
- readYourWrites: true,
42
- }
43
- : {
44
- url: databaseUrl,
45
- };
46
-
47
- export const backendApp = createBackendApp({
48
- db: connection,
49
- express: app,
50
- app: {
51
- name: "{{APP_NAME}}",
52
- urls: {
53
- web: appUrl,
54
- api: serverUrl,
55
- },
56
- },
57
- redis: {
58
- url: redisUrl,
59
- options: { maxRetriesPerRequest: null },
60
- },
61
- resend: resendApiKey ? { apiKey: resendApiKey } : undefined,
62
- email: {
63
- mode: resendApiKey ? "send" : "store",
64
- from: "no-reply@local.m5kdev.test",
65
- systemNotificationEmail: "ops@local.m5kdev.test",
66
- outputDirectory: ".emails",
67
- },
68
- auth: {
69
- factory({ db, services, appConfig }) {
70
- return createBetterAuth({
71
- orm: db.orm as never,
72
- schema: db.schema as never,
73
- services: {
74
- email: services.email.email,
75
- },
76
- app: appConfig,
77
- config: {
78
- waitlist: false,
79
- },
80
- });
81
- },
82
- },
83
- })
84
- .use(emailBackendModule)
85
- .use(authBackendModule)
86
- .use(workflowBackendModule)
87
- .use(notificationBackendModule)
88
- .use(postsBackendModule);
89
-
90
- export const builtBackendApp = backendApp.build();
91
- export const appRouter = builtBackendApp.trpc.router;
92
-
93
- export type AppRouter = InferBackendAppRouter<typeof backendApp>;
94
- export type RouterInputs = inferRouterInputs<AppRouter>;
95
- export type RouterOutputs = inferRouterOutputs<AppRouter>;
1
+ import { createBackendApp, type InferBackendAppRouter } from "@m5kdev/backend/app";
2
+ import { createBetterAuth } from "@m5kdev/backend/modules/auth/auth.lib";
3
+ import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server";
4
+ import cors from "cors";
5
+ import express from "express";
6
+ import {
7
+ authBackendModule,
8
+ emailBackendModule,
9
+ notificationBackendModule,
10
+ postsBackendModule,
11
+ workflowBackendModule,
12
+ } from "./modules";
13
+
14
+ const app = express();
15
+ const appUrl = process.env.VITE_APP_URL ?? "http://localhost:5173";
16
+ const serverUrl = process.env.VITE_SERVER_URL ?? "http://localhost:8080";
17
+
18
+ app.use(express.json());
19
+ app.use(
20
+ cors({
21
+ origin: [appUrl],
22
+ credentials: true,
23
+ methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
24
+ allowedHeaders: ["Content-Type", "Authorization"],
25
+ })
26
+ );
27
+
28
+ const databaseUrl = process.env.DATABASE_URL ?? "file:./local.db";
29
+ const syncUrl = process.env.TURSO_DATABASE_URL;
30
+ const authToken = process.env.TURSO_AUTH_TOKEN;
31
+ const redisUrl = process.env.REDIS_URL ?? "redis://127.0.0.1:6379";
32
+ const resendApiKey = process.env.RESEND_API_KEY;
33
+
34
+ const connection =
35
+ syncUrl && authToken
36
+ ? {
37
+ url: databaseUrl,
38
+ syncUrl,
39
+ authToken,
40
+ syncInterval: 60,
41
+ readYourWrites: true,
42
+ }
43
+ : {
44
+ url: databaseUrl,
45
+ };
46
+
47
+ export const backendApp = createBackendApp({
48
+ db: connection,
49
+ express: app,
50
+ app: {
51
+ name: "{{APP_NAME}}",
52
+ urls: {
53
+ web: appUrl,
54
+ api: serverUrl,
55
+ },
56
+ },
57
+ redis: {
58
+ url: redisUrl,
59
+ options: { maxRetriesPerRequest: null },
60
+ },
61
+ resend: resendApiKey ? { apiKey: resendApiKey } : undefined,
62
+ email: {
63
+ mode: resendApiKey ? "send" : "store",
64
+ from: "no-reply@local.m5kdev.test",
65
+ systemNotificationEmail: "ops@local.m5kdev.test",
66
+ outputDirectory: ".emails",
67
+ },
68
+ auth: {
69
+ factory({ db, services, appConfig }) {
70
+ return createBetterAuth({
71
+ orm: db.orm as never,
72
+ schema: db.schema as never,
73
+ services: {
74
+ email: services.email.email,
75
+ },
76
+ app: appConfig,
77
+ config: {
78
+ waitlist: false,
79
+ },
80
+ });
81
+ },
82
+ },
83
+ })
84
+ .use(emailBackendModule)
85
+ .use(authBackendModule)
86
+ .use(workflowBackendModule)
87
+ .use(notificationBackendModule)
88
+ .use(postsBackendModule);
89
+
90
+ export const builtBackendApp = backendApp.build();
91
+ export const appRouter = builtBackendApp.trpc.router;
92
+
93
+ export type AppRouter = InferBackendAppRouter<typeof backendApp>;
94
+ export type RouterInputs = inferRouterInputs<AppRouter>;
95
+ export type RouterOutputs = inferRouterOutputs<AppRouter>;
@@ -1,7 +1,7 @@
1
- import { builtBackendApp } from "./app";
2
-
3
- export const orm = builtBackendApp.db.orm;
4
- export const schema = builtBackendApp.db.schema;
5
-
6
- export type Orm = typeof orm;
7
- export type Schema = typeof schema;
1
+ import { builtBackendApp } from "./app";
2
+
3
+ export const orm = builtBackendApp.db.orm;
4
+ export const schema = builtBackendApp.db.schema;
5
+
6
+ export type Orm = typeof orm;
7
+ export type Schema = typeof schema;
@@ -1,21 +1,21 @@
1
- import type { Server } from "node:http";
2
- import { builtBackendApp } from "./app";
3
- const port = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 8080;
4
-
5
- let httpServer: Server | undefined;
6
-
7
- function logError(context: string, error: unknown): void {
8
- console.error(`[server] ${context}`, error);
9
- }
10
-
11
- async function shutdown(): Promise<void> {
12
- try {
13
- await builtBackendApp.shutdown();
14
- } catch (e) {
15
- logError("builtBackendApp.shutdown() failed", e);
16
- }
17
- if (httpServer) {
18
- await new Promise<void>((resolve) => {
1
+ import type { Server } from "node:http";
2
+ import { builtBackendApp } from "./app";
3
+ const port = process.env.PORT ? Number.parseInt(process.env.PORT, 10) : 8080;
4
+
5
+ let httpServer: Server | undefined;
6
+
7
+ function logError(context: string, error: unknown): void {
8
+ console.error(`[server] ${context}`, error);
9
+ }
10
+
11
+ async function shutdown(): Promise<void> {
12
+ try {
13
+ await builtBackendApp.shutdown();
14
+ } catch (e) {
15
+ logError("builtBackendApp.shutdown() failed", e);
16
+ }
17
+ if (httpServer) {
18
+ await new Promise<void>((resolve) => {
19
19
  httpServer?.close((err) => {
20
20
  if (err) {
21
21
  logError("HTTP server close failed", err);
@@ -33,23 +33,23 @@ process.once("SIGINT", () => {
33
33
  process.once("SIGTERM", () => {
34
34
  void shutdown();
35
35
  });
36
-
37
- async function start(): Promise<void> {
38
- await builtBackendApp.start();
39
- await new Promise<void>((resolve, reject) => {
40
- httpServer = builtBackendApp.express.app.listen(port, () => {
41
- console.info(`Server running at ${process.env.VITE_SERVER_URL ?? `http://localhost:${port}`}`);
42
- resolve();
43
- });
36
+
37
+ async function start(): Promise<void> {
38
+ await builtBackendApp.start();
39
+ await new Promise<void>((resolve, reject) => {
40
+ httpServer = builtBackendApp.express.app.listen(port, () => {
41
+ console.info(`Server running at ${process.env.VITE_SERVER_URL ?? `http://localhost:${port}`}`);
42
+ resolve();
43
+ });
44
44
  httpServer.on("error", reject);
45
45
  });
46
46
  }
47
47
 
48
- void (async () => {
49
- try {
50
- await start();
51
- } catch (e) {
52
- logError("Fatal: builtBackendApp.start() or HTTP listen failed", e);
53
- process.exit(1);
54
- }
55
- })();
48
+ void (async () => {
49
+ try {
50
+ await start();
51
+ } catch (e) {
52
+ logError("Fatal: builtBackendApp.start() or HTTP listen failed", e);
53
+ process.exit(1);
54
+ }
55
+ })();
@@ -1,6 +1,6 @@
1
- import { builtBackendApp } from "../app";
2
-
3
- export const auth = builtBackendApp.auth!.instance;
4
-
5
- export type Session = typeof auth.$Infer.Session;
6
- export type User = Session["user"];
1
+ import { builtBackendApp } from "../app";
2
+
3
+ export const auth = builtBackendApp.auth!.instance;
4
+
5
+ export type Session = typeof auth.$Infer.Session;
6
+ export type User = Session["user"];
@@ -1,45 +1,45 @@
1
- import { type AnySQLiteColumn, integer, sqliteTable as table, text } from "drizzle-orm/sqlite-core";
2
- import { organizations, teams, users } from "@m5kdev/backend/modules/auth/auth.db";
3
- import { v4 as uuidv4 } from "uuid";
4
-
5
- export function createPostsTables(
6
- references: {
7
- users: { id: AnySQLiteColumn };
8
- organizations: { id: AnySQLiteColumn };
9
- teams: { id: AnySQLiteColumn };
10
- } = {
11
- users,
12
- organizations,
13
- teams,
14
- }
15
- ) {
16
- const posts = table("posts", {
17
- id: text("id").primaryKey().$default(uuidv4),
18
- authorUserId: text("author_user_id").references(() => references.users.id, {
19
- onDelete: "set null",
20
- }),
21
- organizationId: text("organization_id").references(() => references.organizations.id, {
22
- onDelete: "set null",
23
- }),
24
- teamId: text("team_id").references(() => references.teams.id, { onDelete: "set null" }),
25
- title: text("title").notNull(),
26
- slug: text("slug").notNull().unique(),
27
- excerpt: text("excerpt"),
28
- content: text("content").notNull(),
29
- status: text("status").$type<"draft" | "published">().notNull().default("draft"),
30
- publishedAt: integer("published_at", { mode: "timestamp" }),
31
- createdAt: integer("created_at", { mode: "timestamp" })
32
- .notNull()
33
- .$default(() => new Date()),
34
- updatedAt: integer("updated_at", { mode: "timestamp" }),
35
- deletedAt: integer("deleted_at", { mode: "timestamp" }),
36
- });
37
-
38
- return {
39
- posts,
40
- };
41
- }
42
-
43
- const postTables = createPostsTables();
44
-
45
- export const posts = postTables.posts;
1
+ import { type AnySQLiteColumn, integer, sqliteTable as table, text } from "drizzle-orm/sqlite-core";
2
+ import { organizations, teams, users } from "@m5kdev/backend/modules/auth/auth.db";
3
+ import { v4 as uuidv4 } from "uuid";
4
+
5
+ export function createPostsTables(
6
+ references: {
7
+ users: { id: AnySQLiteColumn };
8
+ organizations: { id: AnySQLiteColumn };
9
+ teams: { id: AnySQLiteColumn };
10
+ } = {
11
+ users,
12
+ organizations,
13
+ teams,
14
+ }
15
+ ) {
16
+ const posts = table("posts", {
17
+ id: text("id").primaryKey().$default(uuidv4),
18
+ authorUserId: text("author_user_id").references(() => references.users.id, {
19
+ onDelete: "set null",
20
+ }),
21
+ organizationId: text("organization_id").references(() => references.organizations.id, {
22
+ onDelete: "set null",
23
+ }),
24
+ teamId: text("team_id").references(() => references.teams.id, { onDelete: "set null" }),
25
+ title: text("title").notNull(),
26
+ slug: text("slug").notNull().unique(),
27
+ excerpt: text("excerpt"),
28
+ content: text("content").notNull(),
29
+ status: text("status").$type<"draft" | "published">().notNull().default("draft"),
30
+ publishedAt: integer("published_at", { mode: "timestamp" }),
31
+ createdAt: integer("created_at", { mode: "timestamp" })
32
+ .notNull()
33
+ .$default(() => new Date()),
34
+ updatedAt: integer("updated_at", { mode: "timestamp" }),
35
+ deletedAt: integer("deleted_at", { mode: "timestamp" }),
36
+ });
37
+
38
+ return {
39
+ posts,
40
+ };
41
+ }
42
+
43
+ const postTables = createPostsTables();
44
+
45
+ export const posts = postTables.posts;
@@ -1,37 +1,37 @@
1
- import { defineBackendModule } from "@m5kdev/backend/app";
2
- import { createPostsTRPC } from "./posts.trpc";
3
- import { createPostsTables } from "./posts.db";
4
- import { postsGrants } from "./posts.grants";
5
- import { PostsRepository } from "./posts.repository";
6
- import { PostsService } from "./posts.service";
7
-
8
- export const postsModule = defineBackendModule({
9
- id: "posts",
10
- dependsOn: ["auth"],
11
- db: ({ deps }) => {
12
- const authTables = deps.auth.tables as any;
13
- return {
14
- tables: createPostsTables({
15
- users: authTables.users,
16
- organizations: authTables.organizations,
17
- teams: authTables.teams,
18
- }),
19
- };
20
- },
21
- repositories: ({ db }) => {
22
- const schema = db.schema as any;
23
- return {
24
- posts: new PostsRepository({
25
- orm: db.orm as never,
26
- schema: { posts: schema.posts } as never,
27
- table: schema.posts,
28
- }),
29
- };
30
- },
31
- services: ({ repositories }) => ({
32
- posts: new PostsService({ posts: repositories.posts }, {}, postsGrants),
33
- }),
34
- trpc: ({ trpc, services }) => ({
35
- posts: createPostsTRPC(trpc, services.posts),
36
- }),
37
- });
1
+ import { defineBackendModule } from "@m5kdev/backend/app";
2
+ import { createPostsTRPC } from "./posts.trpc";
3
+ import { createPostsTables } from "./posts.db";
4
+ import { postsGrants } from "./posts.grants";
5
+ import { PostsRepository } from "./posts.repository";
6
+ import { PostsService } from "./posts.service";
7
+
8
+ export const postsModule = defineBackendModule({
9
+ id: "posts",
10
+ dependsOn: ["auth"],
11
+ db: ({ deps }) => {
12
+ const authTables = deps.auth.tables as any;
13
+ return {
14
+ tables: createPostsTables({
15
+ users: authTables.users,
16
+ organizations: authTables.organizations,
17
+ teams: authTables.teams,
18
+ }),
19
+ };
20
+ },
21
+ repositories: ({ db }) => {
22
+ const schema = db.schema as any;
23
+ return {
24
+ posts: new PostsRepository({
25
+ orm: db.orm as never,
26
+ schema: { posts: schema.posts } as never,
27
+ table: schema.posts,
28
+ }),
29
+ };
30
+ },
31
+ services: ({ repositories }) => ({
32
+ posts: new PostsService({ posts: repositories.posts }, {}, postsGrants),
33
+ }),
34
+ trpc: ({ trpc, services }) => ({
35
+ posts: createPostsTRPC(trpc, services.posts),
36
+ }),
37
+ });
@@ -1,18 +1,18 @@
1
- import type {
2
- PostSchema,
3
- PostsListInputSchema,
4
- PostsListOutputSchema,
5
- } from "{{PACKAGE_SCOPE}}/shared/modules/posts/posts.schema";
6
- import { BaseTableRepository } from "@m5kdev/backend/modules/base/base.repository";
7
- import type { ServerResultAsync } from "@m5kdev/backend/utils/types";
8
- import { and, asc, count, desc, eq, isNull, like, ne, or } from "drizzle-orm";
9
- import type { LibSQLDatabase } from "drizzle-orm/libsql";
10
- import { err, ok } from "neverthrow";
11
- import { posts } from "./posts.db";
12
-
13
- const schema = { posts };
14
- type Schema = typeof schema;
15
- type Orm = LibSQLDatabase<Schema>;
1
+ import type {
2
+ PostSchema,
3
+ PostsListInputSchema,
4
+ PostsListOutputSchema,
5
+ } from "{{PACKAGE_SCOPE}}/shared/modules/posts/posts.schema";
6
+ import { BaseTableRepository } from "@m5kdev/backend/modules/base/base.repository";
7
+ import type { ServerResultAsync } from "@m5kdev/backend/utils/types";
8
+ import { and, asc, count, desc, eq, isNull, like, ne, or } from "drizzle-orm";
9
+ import type { LibSQLDatabase } from "drizzle-orm/libsql";
10
+ import { err, ok } from "neverthrow";
11
+ import { posts } from "./posts.db";
12
+
13
+ const schema = { posts };
14
+ type Schema = typeof schema;
15
+ type Orm = LibSQLDatabase<Schema>;
16
16
 
17
17
  export class PostsRepository extends BaseTableRepository<
18
18
  Orm,
@@ -30,11 +30,11 @@ export class PostsRepository extends BaseTableRepository<
30
30
  conditions.push(eq(this.table.status, input.status));
31
31
  }
32
32
 
33
- if (search) {
34
- const escapedSearch = search.replace(/[%_]/g, "\\$&");
35
- const pattern = `%${escapedSearch}%`;
36
- const searchCondition = or(
37
- like(this.table.title, pattern),
33
+ if (search) {
34
+ const escapedSearch = search.replace(/[%_]/g, "\\$&");
35
+ const pattern = `%${escapedSearch}%`;
36
+ const searchCondition = or(
37
+ like(this.table.title, pattern),
38
38
  like(this.table.slug, pattern),
39
39
  like(this.table.excerpt, pattern),
40
40
  like(this.table.content, pattern)
@@ -108,5 +108,5 @@ export class PostsRepository extends BaseTableRepository<
108
108
  slug = `${candidate}-${suffix}`;
109
109
  suffix += 1;
110
110
  }
111
- }
112
- }
111
+ }
112
+ }
@@ -1,155 +1,155 @@
1
- import type {
2
- PostCreateInputSchema,
3
- PostCreateOutputSchema,
1
+ import type {
2
+ PostCreateInputSchema,
3
+ PostCreateOutputSchema,
4
4
  PostPublishInputSchema,
5
5
  PostPublishOutputSchema,
6
6
  PostSoftDeleteInputSchema,
7
7
  PostSoftDeleteOutputSchema,
8
8
  PostsListInputSchema,
9
9
  PostsListOutputSchema,
10
- PostUpdateInputSchema,
11
- PostUpdateOutputSchema,
12
- } from "{{PACKAGE_SCOPE}}/shared/modules/posts/posts.schema";
13
- import { BasePermissionService } from "@m5kdev/backend/modules/base/base.service";
14
- import type { ServerResultAsync } from "@m5kdev/backend/utils/types";
15
- import type { Context } from "@m5kdev/backend/utils/trpc";
16
- import { err, ok } from "neverthrow";
17
- import type { PostsRepository } from "./posts.repository";
18
-
19
- type RequestContext = Context;
20
-
21
- export class PostsService extends BasePermissionService<
22
- { posts: PostsRepository },
23
- Record<string, never>,
24
- RequestContext
25
- > {
26
- readonly list = this.procedure<PostsListInputSchema>("list")
27
- .requireAuth()
28
- .handle(({ input }): ServerResultAsync<PostsListOutputSchema> => {
29
- return this.repository.posts.list(input);
30
- });
31
-
32
- readonly create = this.procedure<PostCreateInputSchema>("create")
33
- .requireAuth()
34
- .access({
35
- action: "write",
36
- entities: ({ ctx }) => ({
37
- organizationId: ctx.session.activeOrganizationId ?? null,
38
- teamId: ctx.session.activeTeamId ?? null,
39
- }),
40
- })
41
- .handle(async ({ input, ctx }): ServerResultAsync<PostCreateOutputSchema> => {
42
- const uniqueSlug = await this.repository.posts.resolveUniqueSlug(
43
- this.slugify(input.slug ?? input.title)
44
- );
45
- if (uniqueSlug.isErr()) {
46
- return err(uniqueSlug.error);
47
- }
48
-
49
- return this.repository.posts.create({
50
- authorUserId: ctx.user.id,
51
- organizationId: ctx.session.activeOrganizationId ?? null,
52
- teamId: ctx.session.activeTeamId ?? null,
53
- title: input.title.trim(),
54
- slug: uniqueSlug.value,
55
- excerpt: this.createExcerpt(input.excerpt, input.content),
56
- content: input.content.trim(),
57
- status: "draft",
58
- }) as ServerResultAsync<PostCreateOutputSchema>;
59
- });
60
-
61
- readonly update = this.procedure<PostUpdateInputSchema>("update")
62
- .requireAuth()
63
- .use("post", async ({ input }) => {
64
- const current = await this.repository.posts.findById(input.id);
65
- if (current.isErr()) {
66
- return err(current.error);
67
- }
68
- if (!current.value || current.value.deletedAt) {
69
- return this.error("NOT_FOUND", "Post not found");
70
- }
71
-
72
- return current.value;
73
- })
74
- .access({
75
- action: "write",
76
- entityStep: "post",
77
- })
78
- .handle(async ({ input }): ServerResultAsync<PostUpdateOutputSchema> => {
79
- const uniqueSlug = await this.repository.posts.resolveUniqueSlug(
80
- this.slugify(input.slug ?? input.title),
81
- input.id
82
- );
83
- if (uniqueSlug.isErr()) {
84
- return err(uniqueSlug.error);
85
- }
86
-
87
- return this.repository.posts.update({
88
- id: input.id,
89
- title: input.title.trim(),
90
- slug: uniqueSlug.value,
91
- excerpt: this.createExcerpt(input.excerpt, input.content),
92
- content: input.content.trim(),
93
- }) as ServerResultAsync<PostUpdateOutputSchema>;
94
- });
95
-
96
- readonly publish = this.procedure<PostPublishInputSchema>("publish")
97
- .requireAuth()
98
- .use("post", async ({ input }) => {
99
- const current = await this.repository.posts.findById(input.id);
100
- if (current.isErr()) {
101
- return err(current.error);
102
- }
103
- if (!current.value || current.value.deletedAt) {
104
- return this.error("NOT_FOUND", "Post not found");
105
- }
106
-
107
- return current.value;
108
- })
109
- .access({
110
- action: "publish",
111
- entityStep: "post",
112
- })
113
- .handle(({ input, state }): ServerResultAsync<PostPublishOutputSchema> => {
114
- return this.repository.posts.update({
115
- id: input.id,
116
- status: "published",
117
- publishedAt: state.post.publishedAt ?? new Date(),
118
- }) as ServerResultAsync<PostPublishOutputSchema>;
119
- });
120
-
121
- readonly softDelete = this.procedure<PostSoftDeleteInputSchema>("softDelete")
122
- .requireAuth()
123
- .use("post", async ({ input }) => {
124
- const current = await this.repository.posts.findById(input.id);
125
- if (current.isErr()) {
126
- return err(current.error);
127
- }
128
- if (!current.value || current.value.deletedAt) {
129
- return this.error("NOT_FOUND", "Post not found");
130
- }
131
-
132
- return current.value;
133
- })
134
- .access({
135
- action: "delete",
136
- entityStep: "post",
137
- })
138
- .handle(async ({ input }): ServerResultAsync<PostSoftDeleteOutputSchema> => {
139
- const updated = await this.repository.posts.update({
140
- id: input.id,
141
- deletedAt: new Date(),
142
- });
143
-
144
- if (updated.isErr()) {
145
- return err(updated.error);
146
- }
147
-
148
- return ok({ id: updated.value.id });
149
- });
150
-
151
- private slugify(value: string): string {
152
- const slug = value
10
+ PostUpdateInputSchema,
11
+ PostUpdateOutputSchema,
12
+ } from "{{PACKAGE_SCOPE}}/shared/modules/posts/posts.schema";
13
+ import { BasePermissionService } from "@m5kdev/backend/modules/base/base.service";
14
+ import type { ServerResultAsync } from "@m5kdev/backend/utils/types";
15
+ import type { Context } from "@m5kdev/backend/utils/trpc";
16
+ import { err, ok } from "neverthrow";
17
+ import type { PostsRepository } from "./posts.repository";
18
+
19
+ type RequestContext = Context;
20
+
21
+ export class PostsService extends BasePermissionService<
22
+ { posts: PostsRepository },
23
+ Record<string, never>,
24
+ RequestContext
25
+ > {
26
+ readonly list = this.procedure<PostsListInputSchema>("list")
27
+ .requireAuth()
28
+ .handle(({ input }): ServerResultAsync<PostsListOutputSchema> => {
29
+ return this.repository.posts.list(input);
30
+ });
31
+
32
+ readonly create = this.procedure<PostCreateInputSchema>("create")
33
+ .requireAuth()
34
+ .access({
35
+ action: "write",
36
+ entities: ({ ctx }) => ({
37
+ organizationId: ctx.session.activeOrganizationId ?? null,
38
+ teamId: ctx.session.activeTeamId ?? null,
39
+ }),
40
+ })
41
+ .handle(async ({ input, ctx }): ServerResultAsync<PostCreateOutputSchema> => {
42
+ const uniqueSlug = await this.repository.posts.resolveUniqueSlug(
43
+ this.slugify(input.slug ?? input.title)
44
+ );
45
+ if (uniqueSlug.isErr()) {
46
+ return err(uniqueSlug.error);
47
+ }
48
+
49
+ return this.repository.posts.create({
50
+ authorUserId: ctx.user.id,
51
+ organizationId: ctx.session.activeOrganizationId ?? null,
52
+ teamId: ctx.session.activeTeamId ?? null,
53
+ title: input.title.trim(),
54
+ slug: uniqueSlug.value,
55
+ excerpt: this.createExcerpt(input.excerpt, input.content),
56
+ content: input.content.trim(),
57
+ status: "draft",
58
+ }) as ServerResultAsync<PostCreateOutputSchema>;
59
+ });
60
+
61
+ readonly update = this.procedure<PostUpdateInputSchema>("update")
62
+ .requireAuth()
63
+ .use("post", async ({ input }) => {
64
+ const current = await this.repository.posts.findById(input.id);
65
+ if (current.isErr()) {
66
+ return err(current.error);
67
+ }
68
+ if (!current.value || current.value.deletedAt) {
69
+ return this.error("NOT_FOUND", "Post not found");
70
+ }
71
+
72
+ return current.value;
73
+ })
74
+ .access({
75
+ action: "write",
76
+ entityStep: "post",
77
+ })
78
+ .handle(async ({ input }): ServerResultAsync<PostUpdateOutputSchema> => {
79
+ const uniqueSlug = await this.repository.posts.resolveUniqueSlug(
80
+ this.slugify(input.slug ?? input.title),
81
+ input.id
82
+ );
83
+ if (uniqueSlug.isErr()) {
84
+ return err(uniqueSlug.error);
85
+ }
86
+
87
+ return this.repository.posts.update({
88
+ id: input.id,
89
+ title: input.title.trim(),
90
+ slug: uniqueSlug.value,
91
+ excerpt: this.createExcerpt(input.excerpt, input.content),
92
+ content: input.content.trim(),
93
+ }) as ServerResultAsync<PostUpdateOutputSchema>;
94
+ });
95
+
96
+ readonly publish = this.procedure<PostPublishInputSchema>("publish")
97
+ .requireAuth()
98
+ .use("post", async ({ input }) => {
99
+ const current = await this.repository.posts.findById(input.id);
100
+ if (current.isErr()) {
101
+ return err(current.error);
102
+ }
103
+ if (!current.value || current.value.deletedAt) {
104
+ return this.error("NOT_FOUND", "Post not found");
105
+ }
106
+
107
+ return current.value;
108
+ })
109
+ .access({
110
+ action: "publish",
111
+ entityStep: "post",
112
+ })
113
+ .handle(({ input, state }): ServerResultAsync<PostPublishOutputSchema> => {
114
+ return this.repository.posts.update({
115
+ id: input.id,
116
+ status: "published",
117
+ publishedAt: state.post.publishedAt ?? new Date(),
118
+ }) as ServerResultAsync<PostPublishOutputSchema>;
119
+ });
120
+
121
+ readonly softDelete = this.procedure<PostSoftDeleteInputSchema>("softDelete")
122
+ .requireAuth()
123
+ .use("post", async ({ input }) => {
124
+ const current = await this.repository.posts.findById(input.id);
125
+ if (current.isErr()) {
126
+ return err(current.error);
127
+ }
128
+ if (!current.value || current.value.deletedAt) {
129
+ return this.error("NOT_FOUND", "Post not found");
130
+ }
131
+
132
+ return current.value;
133
+ })
134
+ .access({
135
+ action: "delete",
136
+ entityStep: "post",
137
+ })
138
+ .handle(async ({ input }): ServerResultAsync<PostSoftDeleteOutputSchema> => {
139
+ const updated = await this.repository.posts.update({
140
+ id: input.id,
141
+ deletedAt: new Date(),
142
+ });
143
+
144
+ if (updated.isErr()) {
145
+ return err(updated.error);
146
+ }
147
+
148
+ return ok({ id: updated.value.id });
149
+ });
150
+
151
+ private slugify(value: string): string {
152
+ const slug = value
153
153
  .trim()
154
154
  .toLowerCase()
155
155
  .replace(/[^a-z0-9]+/g, "-")
@@ -1,6 +1,6 @@
1
- import {
2
- postCreateInputSchema,
3
- postCreateOutputSchema,
1
+ import {
2
+ postCreateInputSchema,
3
+ postCreateOutputSchema,
4
4
  postPublishInputSchema,
5
5
  postPublishOutputSchema,
6
6
  postSoftDeleteInputSchema,
@@ -8,41 +8,41 @@ import {
8
8
  postsListInputSchema,
9
9
  postsListOutputSchema,
10
10
  postUpdateInputSchema,
11
- postUpdateOutputSchema,
12
- } from "{{PACKAGE_SCOPE}}/shared/modules/posts/posts.schema";
13
- import { handleTRPCResult, type TRPCMethods } from "@m5kdev/backend/utils/trpc";
14
- import type { PostsService } from "./posts.service";
15
-
16
- export function createPostsTRPC(
17
- { router, privateProcedure: procedure }: TRPCMethods,
18
- postsService: PostsService
19
- ) {
20
- return router({
21
- list: procedure
22
- .input(postsListInputSchema)
23
- .output(postsListOutputSchema)
24
- .query(async ({ ctx, input }) => handleTRPCResult(await postsService.list(input ?? {}, ctx))),
25
-
26
- create: procedure
27
- .input(postCreateInputSchema)
28
- .output(postCreateOutputSchema)
29
- .mutation(async ({ ctx, input }) => handleTRPCResult(await postsService.create(input, ctx))),
30
-
31
- update: procedure
32
- .input(postUpdateInputSchema)
33
- .output(postUpdateOutputSchema)
34
- .mutation(async ({ ctx, input }) => handleTRPCResult(await postsService.update(input, ctx))),
35
-
36
- publish: procedure
37
- .input(postPublishInputSchema)
38
- .output(postPublishOutputSchema)
39
- .mutation(async ({ ctx, input }) => handleTRPCResult(await postsService.publish(input, ctx))),
40
-
41
- softDelete: procedure
42
- .input(postSoftDeleteInputSchema)
43
- .output(postSoftDeleteOutputSchema)
44
- .mutation(async ({ ctx, input }) =>
45
- handleTRPCResult(await postsService.softDelete(input, ctx))
46
- ),
47
- });
48
- }
11
+ postUpdateOutputSchema,
12
+ } from "{{PACKAGE_SCOPE}}/shared/modules/posts/posts.schema";
13
+ import { handleTRPCResult, type TRPCMethods } from "@m5kdev/backend/utils/trpc";
14
+ import type { PostsService } from "./posts.service";
15
+
16
+ export function createPostsTRPC(
17
+ { router, privateProcedure: procedure }: TRPCMethods,
18
+ postsService: PostsService
19
+ ) {
20
+ return router({
21
+ list: procedure
22
+ .input(postsListInputSchema)
23
+ .output(postsListOutputSchema)
24
+ .query(async ({ ctx, input }) => handleTRPCResult(await postsService.list(input ?? {}, ctx))),
25
+
26
+ create: procedure
27
+ .input(postCreateInputSchema)
28
+ .output(postCreateOutputSchema)
29
+ .mutation(async ({ ctx, input }) => handleTRPCResult(await postsService.create(input, ctx))),
30
+
31
+ update: procedure
32
+ .input(postUpdateInputSchema)
33
+ .output(postUpdateOutputSchema)
34
+ .mutation(async ({ ctx, input }) => handleTRPCResult(await postsService.update(input, ctx))),
35
+
36
+ publish: procedure
37
+ .input(postPublishInputSchema)
38
+ .output(postPublishOutputSchema)
39
+ .mutation(async ({ ctx, input }) => handleTRPCResult(await postsService.publish(input, ctx))),
40
+
41
+ softDelete: procedure
42
+ .input(postSoftDeleteInputSchema)
43
+ .output(postSoftDeleteOutputSchema)
44
+ .mutation(async ({ ctx, input }) =>
45
+ handleTRPCResult(await postsService.softDelete(input, ctx))
46
+ ),
47
+ });
48
+ }
@@ -1,37 +1,37 @@
1
- import { defineBackendModules } from "@m5kdev/backend/app";
2
- import { createAuthBackendModule } from "@m5kdev/backend/modules/auth/auth.module";
3
- import { createEmailBackendModule } from "@m5kdev/backend/modules/email/email.module";
4
- import { createNotificationBackendModule } from "@m5kdev/backend/modules/notification/notification.module";
5
- import { createWorkflowBackendModule } from "@m5kdev/backend/modules/workflow/workflow.module";
6
- import { templates } from "{{PACKAGE_SCOPE}}/email";
7
- import { postsModule } from "./modules/posts/posts.module";
8
-
9
- export const emailBackendModule = createEmailBackendModule({
10
- templates: templates as never,
11
- });
12
-
13
- export const authBackendModule = createAuthBackendModule({
14
- emailModuleId: "email",
15
- });
16
-
17
- export const workflowBackendModule = createWorkflowBackendModule({
18
- queues: {
19
- fast: { concurrency: 5 },
20
- },
21
- defaultQueue: "fast",
22
- defaults: {
23
- timeout: 60_000,
24
- jobOptions: { removeOnComplete: { age: 3600 } },
25
- },
26
- });
27
-
28
- export const notificationBackendModule = createNotificationBackendModule();
29
- export const postsBackendModule = postsModule;
30
-
31
- export const backendModules = defineBackendModules([
32
- emailBackendModule,
33
- authBackendModule,
34
- workflowBackendModule,
35
- notificationBackendModule,
36
- postsBackendModule,
37
- ] as const);
1
+ import { defineBackendModules } from "@m5kdev/backend/app";
2
+ import { createAuthBackendModule } from "@m5kdev/backend/modules/auth/auth.module";
3
+ import { createEmailBackendModule } from "@m5kdev/backend/modules/email/email.module";
4
+ import { createNotificationBackendModule } from "@m5kdev/backend/modules/notification/notification.module";
5
+ import { createWorkflowBackendModule } from "@m5kdev/backend/modules/workflow/workflow.module";
6
+ import { templates } from "{{PACKAGE_SCOPE}}/email";
7
+ import { postsModule } from "./modules/posts/posts.module";
8
+
9
+ export const emailBackendModule = createEmailBackendModule({
10
+ templates: templates as never,
11
+ });
12
+
13
+ export const authBackendModule = createAuthBackendModule({
14
+ emailModuleId: "email",
15
+ });
16
+
17
+ export const workflowBackendModule = createWorkflowBackendModule({
18
+ queues: {
19
+ fast: { concurrency: 5 },
20
+ },
21
+ defaultQueue: "fast",
22
+ defaults: {
23
+ timeout: 60_000,
24
+ jobOptions: { removeOnComplete: { age: 3600 } },
25
+ },
26
+ });
27
+
28
+ export const notificationBackendModule = createNotificationBackendModule();
29
+ export const postsBackendModule = postsModule;
30
+
31
+ export const backendModules = defineBackendModules([
32
+ emailBackendModule,
33
+ authBackendModule,
34
+ workflowBackendModule,
35
+ notificationBackendModule,
36
+ postsBackendModule,
37
+ ] as const);
@@ -1,6 +1,6 @@
1
- import { builtBackendApp } from "./app";
2
-
3
- export const authRepository = builtBackendApp.modules.auth.repositories.auth;
4
- export const workflowRepository = builtBackendApp.modules.workflow.repositories.workflow;
5
- export const notificationRepository = builtBackendApp.modules.notification.repositories.notification;
6
- export const postsRepository = builtBackendApp.modules.posts.repositories.posts;
1
+ import { builtBackendApp } from "./app";
2
+
3
+ export const authRepository = builtBackendApp.modules.auth.repositories.auth;
4
+ export const workflowRepository = builtBackendApp.modules.workflow.repositories.workflow;
5
+ export const notificationRepository = builtBackendApp.modules.notification.repositories.notification;
6
+ export const postsRepository = builtBackendApp.modules.posts.repositories.posts;
@@ -1,14 +1,14 @@
1
- import { defineBackendModule, defineBackendModules } from "@m5kdev/backend/app";
2
- import { authBackendModule, notificationBackendModule, postsBackendModule, workflowBackendModule } from "./modules";
3
-
4
- export const emailSchemaModule = defineBackendModule({
5
- id: "email",
6
- });
7
-
8
- export const backendSchemaModules = defineBackendModules([
9
- emailSchemaModule,
10
- authBackendModule,
11
- workflowBackendModule,
12
- notificationBackendModule,
13
- postsBackendModule,
14
- ] as const);
1
+ import { defineBackendModule, defineBackendModules } from "@m5kdev/backend/app";
2
+ import { authBackendModule, notificationBackendModule, postsBackendModule, workflowBackendModule } from "./modules";
3
+
4
+ export const emailSchemaModule = defineBackendModule({
5
+ id: "email",
6
+ });
7
+
8
+ export const backendSchemaModules = defineBackendModules([
9
+ emailSchemaModule,
10
+ authBackendModule,
11
+ workflowBackendModule,
12
+ notificationBackendModule,
13
+ postsBackendModule,
14
+ ] as const);
@@ -1,7 +1,7 @@
1
- import { builtBackendApp, emailService } from "./app";
2
-
3
- export { emailService };
4
-
5
- export const authService = builtBackendApp.modules.auth.services.auth;
6
- export const postsService = builtBackendApp.modules.posts.services.posts;
7
- export const notificationService = builtBackendApp.modules.notification.services.notification;
1
+ import { builtBackendApp, emailService } from "./app";
2
+
3
+ export { emailService };
4
+
5
+ export const authService = builtBackendApp.modules.auth.services.auth;
6
+ export const postsService = builtBackendApp.modules.posts.services.posts;
7
+ export const notificationService = builtBackendApp.modules.notification.services.notification;
@@ -1,6 +1,6 @@
1
- export {
2
- appRouter,
3
- type AppRouter,
4
- type RouterInputs,
5
- type RouterOutputs,
6
- } from "./app";
1
+ export {
2
+ appRouter,
3
+ type AppRouter,
4
+ type RouterInputs,
5
+ type RouterOutputs,
6
+ } from "./app";
@@ -1,8 +1,8 @@
1
- import { builtBackendApp } from "../app";
2
-
3
- export const router = builtBackendApp.trpc.methods.router;
4
- export const publicProcedure = builtBackendApp.trpc.methods.publicProcedure;
5
- export const procedure = builtBackendApp.trpc.methods.privateProcedure;
6
- export const adminProcedure = builtBackendApp.trpc.methods.adminProcedure;
7
-
8
- export const trpcObject = builtBackendApp.trpc.methods;
1
+ import { builtBackendApp } from "../app";
2
+
3
+ export const router = builtBackendApp.trpc.methods.router;
4
+ export const publicProcedure = builtBackendApp.trpc.methods.publicProcedure;
5
+ export const procedure = builtBackendApp.trpc.methods.privateProcedure;
6
+ export const adminProcedure = builtBackendApp.trpc.methods.adminProcedure;
7
+
8
+ export const trpcObject = builtBackendApp.trpc.methods;
@@ -1,4 +1,4 @@
1
- import { builtBackendApp } from "./app";
2
-
3
- export const workflowService = builtBackendApp.modules.workflow.services.workflow;
4
- export const workflowRegistry = builtBackendApp.workflow!.registry;
1
+ import { builtBackendApp } from "./app";
2
+
3
+ export const workflowService = builtBackendApp.modules.workflow.services.workflow;
4
+ export const workflowRegistry = builtBackendApp.workflow!.registry;