@kuckit/application 1.0.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.
@@ -0,0 +1,78 @@
1
+ import { UserRepository } from "@kuckit/domain/ports/user-repository";
2
+ import { User } from "@kuckit/domain/entities/user";
3
+ import { EventPublisher } from "@kuckit/domain/ports/event-publisher";
4
+ import { Clock } from "@kuckit/domain/ports/clock";
5
+ import { CacheStore, DomainEvent, EventBus, EventHandler, EventMap, EventMeta, EventName, RateLimiterStore, TypedDomainEvent } from "@kuckit/domain";
6
+
7
+ //#region src/usecases/get-user-profile.d.ts
8
+ /**
9
+ * Dependencies required by the use case
10
+ */
11
+ interface GetUserProfileDeps {
12
+ readonly userRepository: UserRepository;
13
+ }
14
+ /**
15
+ * Input for the use case
16
+ */
17
+ interface GetUserProfileInput {
18
+ readonly userId: string;
19
+ }
20
+ /**
21
+ * Use case: Get user profile
22
+ * Pure business logic with no infrastructure dependencies
23
+ *
24
+ * No events for read operations - this is a query use case that doesn't
25
+ * modify state, so no domain events are published.
26
+ */
27
+ declare const makeGetUserProfile: (deps: GetUserProfileDeps) => (input: GetUserProfileInput) => Promise<User>;
28
+ //#endregion
29
+ //#region src/usecases/update-user-profile.d.ts
30
+ /**
31
+ * Dependencies required by the use case
32
+ */
33
+ interface UpdateUserProfileDeps {
34
+ readonly userRepository: UserRepository;
35
+ readonly eventPublisher: EventPublisher;
36
+ readonly clock: Clock;
37
+ }
38
+ /**
39
+ * Input for the use case
40
+ */
41
+ interface UpdateUserProfileInput {
42
+ readonly userId: string;
43
+ readonly updates: {
44
+ readonly name?: string;
45
+ readonly email?: string;
46
+ readonly emailVerified?: boolean;
47
+ };
48
+ }
49
+ /**
50
+ * Use case: Update user profile
51
+ * Publishes 'user.updated' event after successful update
52
+ */
53
+ declare const makeUpdateUserProfile: (deps: UpdateUserProfileDeps) => (input: UpdateUserProfileInput) => Promise<User>;
54
+ //#endregion
55
+ //#region src/usecases/create-user.d.ts
56
+ /**
57
+ * Dependencies required by the use case
58
+ */
59
+ interface CreateUserDeps {
60
+ readonly userRepository: UserRepository;
61
+ readonly eventPublisher: EventPublisher;
62
+ readonly clock: Clock;
63
+ }
64
+ /**
65
+ * Input for the use case
66
+ */
67
+ interface CreateUserInput {
68
+ readonly name: string;
69
+ readonly email: string;
70
+ readonly emailVerified: boolean;
71
+ }
72
+ /**
73
+ * Use case: Create user
74
+ * Publishes 'user.created' event after successful creation
75
+ */
76
+ declare const makeCreateUser: (deps: CreateUserDeps) => (input: CreateUserInput) => Promise<User>;
77
+ //#endregion
78
+ export { type CacheStore, CreateUserDeps, CreateUserInput, type DomainEvent, type EventBus, type EventHandler, type EventMap, type EventMeta, type EventName, GetUserProfileDeps, GetUserProfileInput, type RateLimiterStore, type TypedDomainEvent, UpdateUserProfileDeps, UpdateUserProfileInput, makeCreateUser, makeGetUserProfile, makeUpdateUserProfile };
package/dist/index.js ADDED
@@ -0,0 +1,77 @@
1
+ import { randomUUID } from "crypto";
2
+
3
+ //#region src/usecases/get-user-profile.ts
4
+ /**
5
+ * Use case: Get user profile
6
+ * Pure business logic with no infrastructure dependencies
7
+ *
8
+ * No events for read operations - this is a query use case that doesn't
9
+ * modify state, so no domain events are published.
10
+ */
11
+ const makeGetUserProfile = (deps) => {
12
+ return async (input) => {
13
+ const user = await deps.userRepository.findById(input.userId);
14
+ if (!user) throw new Error("USER_NOT_FOUND");
15
+ return user;
16
+ };
17
+ };
18
+
19
+ //#endregion
20
+ //#region src/usecases/update-user-profile.ts
21
+ /**
22
+ * Use case: Update user profile
23
+ * Publishes 'user.updated' event after successful update
24
+ */
25
+ const makeUpdateUserProfile = (deps) => {
26
+ return async (input) => {
27
+ const existingUser = await deps.userRepository.findById(input.userId);
28
+ if (!existingUser) throw new Error("USER_NOT_FOUND");
29
+ const updatedUser = {
30
+ ...existingUser,
31
+ name: input.updates.name ?? existingUser.name,
32
+ email: input.updates.email ?? existingUser.email,
33
+ emailVerified: input.updates.emailVerified ?? existingUser.emailVerified,
34
+ updatedAt: deps.clock.now()
35
+ };
36
+ await deps.userRepository.save(updatedUser);
37
+ await deps.eventPublisher.publish("user.updated", {
38
+ userId: updatedUser.id,
39
+ changes: input.updates,
40
+ updatedAt: updatedUser.updatedAt
41
+ }, updatedUser.id);
42
+ return updatedUser;
43
+ };
44
+ };
45
+
46
+ //#endregion
47
+ //#region src/usecases/create-user.ts
48
+ /**
49
+ * Use case: Create user
50
+ * Publishes 'user.created' event after successful creation
51
+ */
52
+ const makeCreateUser = (deps) => {
53
+ return async (input) => {
54
+ if (await deps.userRepository.findByEmail(input.email)) throw new Error("USER_ALREADY_EXISTS");
55
+ const now = deps.clock.now();
56
+ const newUser = {
57
+ id: randomUUID(),
58
+ name: input.name,
59
+ email: input.email,
60
+ emailVerified: input.emailVerified,
61
+ permissions: ["modules:read"],
62
+ createdAt: now,
63
+ updatedAt: now
64
+ };
65
+ await deps.userRepository.save(newUser);
66
+ await deps.eventPublisher.publish("user.created", {
67
+ userId: newUser.id,
68
+ email: newUser.email,
69
+ name: newUser.name,
70
+ createdAt: newUser.createdAt
71
+ }, newUser.id);
72
+ return newUser;
73
+ };
74
+ };
75
+
76
+ //#endregion
77
+ export { makeCreateUser, makeGetUserProfile, makeUpdateUserProfile };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@kuckit/application",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "src/index.ts",
6
+ "types": "src/index.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "exports": {
11
+ ".": {
12
+ "types": "./src/index.ts",
13
+ "default": "./src/index.ts"
14
+ },
15
+ "./*": {
16
+ "types": "./src/*.ts",
17
+ "default": "./src/*.ts"
18
+ }
19
+ },
20
+ "publishConfig": {
21
+ "main": "dist/index.js",
22
+ "types": "dist/index.d.ts",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ },
28
+ "./*": {
29
+ "types": "./dist/*.d.ts",
30
+ "default": "./dist/*.js"
31
+ }
32
+ }
33
+ },
34
+ "scripts": {
35
+ "build": "tsdown"
36
+ },
37
+ "dependencies": {
38
+ "@kuckit/domain": "workspace:*"
39
+ },
40
+ "devDependencies": {
41
+ "tsdown": "catalog:"
42
+ },
43
+ "peerDependencies": {
44
+ "typescript": "^5"
45
+ }
46
+ }
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './usecases'
2
+ export * from './events'
3
+ export * from './ports'