@clipboard-health/ai-rules 1.5.5 → 1.5.7
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.
- package/backend/AGENTS.md +56 -25
- package/fullstack/AGENTS.md +56 -25
- package/package.json +1 -1
package/backend/AGENTS.md
CHANGED
|
@@ -37,43 +37,76 @@ Send notifications through [Knock](https://docs.knock.app) using the `@clipboard
|
|
|
37
37
|
});
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
2. Add types and the job name to the module's logic directory if it exists, else module root:
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
import { type BaseHandler } from "@clipboard-health/background-jobs-adapter";
|
|
44
43
|
import { type NotificationData } from "@clipboard-health/notifications";
|
|
45
|
-
import { isFailure } from "@clipboard-health/util-ts";
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
export type ExampleNotificationData = NotificationData<{
|
|
45
|
+
type ExampleNotificationData = NotificationData<{
|
|
50
46
|
workplaceId: string;
|
|
51
47
|
}>;
|
|
52
48
|
|
|
49
|
+
export type ExampleNotificationDataJob = ExampleNotificationData["Job"];
|
|
50
|
+
export type ExampleNotificationDataEnqueue = ExampleNotificationData["Enqueue"];
|
|
51
|
+
|
|
52
|
+
export type ExampleNotificationDo = ExampleNotificationDataJob & { attempt: number };
|
|
53
|
+
|
|
53
54
|
export const EXAMPLE_NOTIFICATION_JOB_NAME = "ExampleNotificationJob";
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
3. Implement a minimal job in the module's logic/job directory if it exists, else module root. The job calls off to a NestJS service for any business logic and to send the notification:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { type BaseHandler } from "@clipboard-health/background-jobs-adapter";
|
|
61
|
+
import { isFailure } from "@clipboard-health/util-ts";
|
|
54
62
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
import {
|
|
64
|
+
EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
65
|
+
type ExampleNotificationDataJob,
|
|
66
|
+
} from "./exampleNotification.constants";
|
|
67
|
+
import { type ExampleNotificationService } from "./exampleNotification.service";
|
|
68
|
+
import { CBHLogger } from "./setup";
|
|
69
|
+
|
|
70
|
+
// For mongo-jobs, you'll implement HandlerInterface<ExampleNotificationDataJob>
|
|
71
|
+
// For background-jobs-postgres, you'll implement Handler<ExampleNotificationDataJob>
|
|
72
|
+
export class ExampleNotificationJob implements BaseHandler<ExampleNotificationDataJob> {
|
|
58
73
|
public name = EXAMPLE_NOTIFICATION_JOB_NAME;
|
|
74
|
+
private readonly logger = new CBHLogger({
|
|
75
|
+
defaultMeta: {
|
|
76
|
+
logContext: EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
59
79
|
|
|
60
80
|
constructor(private readonly service: ExampleNotificationService) {}
|
|
61
81
|
|
|
62
|
-
async perform(data:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Include the job's attempts count for debugging, this is called `retryAttempts` in `background-jobs-postgres`.
|
|
66
|
-
attempt: job.attemptsCount + 1,
|
|
82
|
+
async perform(data: ExampleNotificationDataJob, job: { attemptsCount: number }) {
|
|
83
|
+
this.logger.info("Processing", {
|
|
84
|
+
workflowKey: data.workflowKey,
|
|
67
85
|
});
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
try {
|
|
88
|
+
const result = await this.service.sendNotification({
|
|
89
|
+
...data,
|
|
90
|
+
// Include the job's attempts count for debugging, this is called `retryAttempts` in `background-jobs-postgres`.
|
|
91
|
+
attempt: job.attemptsCount + 1,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (isFailure(result)) {
|
|
95
|
+
throw result.error;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.logger.info("Success", {
|
|
99
|
+
workflowKey: data.workflowKey,
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
this.logger.error("Failed", { error, data });
|
|
103
|
+
throw error;
|
|
71
104
|
}
|
|
72
105
|
}
|
|
73
106
|
}
|
|
74
107
|
```
|
|
75
108
|
|
|
76
|
-
|
|
109
|
+
4. Search the service for a constant that stores workflow keys. If there isn't one, create and export it:
|
|
77
110
|
|
|
78
111
|
```ts
|
|
79
112
|
export const WORKFLOW_KEYS = {
|
|
@@ -81,18 +114,18 @@ Send notifications through [Knock](https://docs.knock.app) using the `@clipboard
|
|
|
81
114
|
} as const;
|
|
82
115
|
```
|
|
83
116
|
|
|
84
|
-
|
|
117
|
+
5. Enqueue the job:
|
|
85
118
|
|
|
86
119
|
```ts
|
|
87
120
|
import {
|
|
88
121
|
EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
89
|
-
type
|
|
90
|
-
} from "./exampleNotification.
|
|
122
|
+
type ExampleNotificationDataEnqueue,
|
|
123
|
+
} from "./exampleNotification.constants";
|
|
91
124
|
import { notificationJobEnqueuer } from "./notificationJobEnqueuer";
|
|
92
125
|
import { WORKFLOW_KEYS } from "./workflowKeys";
|
|
93
126
|
|
|
94
127
|
async function enqueueNotificationJob() {
|
|
95
|
-
await notificationJobEnqueuer.enqueueOneOrMore<
|
|
128
|
+
await notificationJobEnqueuer.enqueueOneOrMore<ExampleNotificationDataEnqueue>(
|
|
96
129
|
EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
97
130
|
// Important: Read the TypeDoc documentation for additional context.
|
|
98
131
|
{
|
|
@@ -123,14 +156,12 @@ Send notifications through [Knock](https://docs.knock.app) using the `@clipboard
|
|
|
123
156
|
void enqueueNotificationJob();
|
|
124
157
|
```
|
|
125
158
|
|
|
126
|
-
|
|
159
|
+
6. Create the NestJS service in the module's logic directory if it exists, else module root. Trigger the NotificationClient:
|
|
127
160
|
|
|
128
161
|
```ts
|
|
129
162
|
import { type NotificationClient } from "@clipboard-health/notifications";
|
|
130
163
|
|
|
131
|
-
import { type
|
|
132
|
-
|
|
133
|
-
type ExampleNotificationDo = ExampleNotificationData["Job"] & { attempt: number };
|
|
164
|
+
import { type ExampleNotificationDo } from "./exampleNotification.constants";
|
|
134
165
|
|
|
135
166
|
export class ExampleNotificationService {
|
|
136
167
|
constructor(private readonly client: NotificationClient) {}
|
package/fullstack/AGENTS.md
CHANGED
|
@@ -37,43 +37,76 @@ Send notifications through [Knock](https://docs.knock.app) using the `@clipboard
|
|
|
37
37
|
});
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
2. Add types and the job name to the module's logic directory if it exists, else module root:
|
|
41
41
|
|
|
42
42
|
```ts
|
|
43
|
-
import { type BaseHandler } from "@clipboard-health/background-jobs-adapter";
|
|
44
43
|
import { type NotificationData } from "@clipboard-health/notifications";
|
|
45
|
-
import { isFailure } from "@clipboard-health/util-ts";
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
export type ExampleNotificationData = NotificationData<{
|
|
45
|
+
type ExampleNotificationData = NotificationData<{
|
|
50
46
|
workplaceId: string;
|
|
51
47
|
}>;
|
|
52
48
|
|
|
49
|
+
export type ExampleNotificationDataJob = ExampleNotificationData["Job"];
|
|
50
|
+
export type ExampleNotificationDataEnqueue = ExampleNotificationData["Enqueue"];
|
|
51
|
+
|
|
52
|
+
export type ExampleNotificationDo = ExampleNotificationDataJob & { attempt: number };
|
|
53
|
+
|
|
53
54
|
export const EXAMPLE_NOTIFICATION_JOB_NAME = "ExampleNotificationJob";
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
3. Implement a minimal job in the module's logic/job directory if it exists, else module root. The job calls off to a NestJS service for any business logic and to send the notification:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { type BaseHandler } from "@clipboard-health/background-jobs-adapter";
|
|
61
|
+
import { isFailure } from "@clipboard-health/util-ts";
|
|
54
62
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
import {
|
|
64
|
+
EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
65
|
+
type ExampleNotificationDataJob,
|
|
66
|
+
} from "./exampleNotification.constants";
|
|
67
|
+
import { type ExampleNotificationService } from "./exampleNotification.service";
|
|
68
|
+
import { CBHLogger } from "./setup";
|
|
69
|
+
|
|
70
|
+
// For mongo-jobs, you'll implement HandlerInterface<ExampleNotificationDataJob>
|
|
71
|
+
// For background-jobs-postgres, you'll implement Handler<ExampleNotificationDataJob>
|
|
72
|
+
export class ExampleNotificationJob implements BaseHandler<ExampleNotificationDataJob> {
|
|
58
73
|
public name = EXAMPLE_NOTIFICATION_JOB_NAME;
|
|
74
|
+
private readonly logger = new CBHLogger({
|
|
75
|
+
defaultMeta: {
|
|
76
|
+
logContext: EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
59
79
|
|
|
60
80
|
constructor(private readonly service: ExampleNotificationService) {}
|
|
61
81
|
|
|
62
|
-
async perform(data:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// Include the job's attempts count for debugging, this is called `retryAttempts` in `background-jobs-postgres`.
|
|
66
|
-
attempt: job.attemptsCount + 1,
|
|
82
|
+
async perform(data: ExampleNotificationDataJob, job: { attemptsCount: number }) {
|
|
83
|
+
this.logger.info("Processing", {
|
|
84
|
+
workflowKey: data.workflowKey,
|
|
67
85
|
});
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
87
|
+
try {
|
|
88
|
+
const result = await this.service.sendNotification({
|
|
89
|
+
...data,
|
|
90
|
+
// Include the job's attempts count for debugging, this is called `retryAttempts` in `background-jobs-postgres`.
|
|
91
|
+
attempt: job.attemptsCount + 1,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (isFailure(result)) {
|
|
95
|
+
throw result.error;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
this.logger.info("Success", {
|
|
99
|
+
workflowKey: data.workflowKey,
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
this.logger.error("Failed", { error, data });
|
|
103
|
+
throw error;
|
|
71
104
|
}
|
|
72
105
|
}
|
|
73
106
|
}
|
|
74
107
|
```
|
|
75
108
|
|
|
76
|
-
|
|
109
|
+
4. Search the service for a constant that stores workflow keys. If there isn't one, create and export it:
|
|
77
110
|
|
|
78
111
|
```ts
|
|
79
112
|
export const WORKFLOW_KEYS = {
|
|
@@ -81,18 +114,18 @@ Send notifications through [Knock](https://docs.knock.app) using the `@clipboard
|
|
|
81
114
|
} as const;
|
|
82
115
|
```
|
|
83
116
|
|
|
84
|
-
|
|
117
|
+
5. Enqueue the job:
|
|
85
118
|
|
|
86
119
|
```ts
|
|
87
120
|
import {
|
|
88
121
|
EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
89
|
-
type
|
|
90
|
-
} from "./exampleNotification.
|
|
122
|
+
type ExampleNotificationDataEnqueue,
|
|
123
|
+
} from "./exampleNotification.constants";
|
|
91
124
|
import { notificationJobEnqueuer } from "./notificationJobEnqueuer";
|
|
92
125
|
import { WORKFLOW_KEYS } from "./workflowKeys";
|
|
93
126
|
|
|
94
127
|
async function enqueueNotificationJob() {
|
|
95
|
-
await notificationJobEnqueuer.enqueueOneOrMore<
|
|
128
|
+
await notificationJobEnqueuer.enqueueOneOrMore<ExampleNotificationDataEnqueue>(
|
|
96
129
|
EXAMPLE_NOTIFICATION_JOB_NAME,
|
|
97
130
|
// Important: Read the TypeDoc documentation for additional context.
|
|
98
131
|
{
|
|
@@ -123,14 +156,12 @@ Send notifications through [Knock](https://docs.knock.app) using the `@clipboard
|
|
|
123
156
|
void enqueueNotificationJob();
|
|
124
157
|
```
|
|
125
158
|
|
|
126
|
-
|
|
159
|
+
6. Create the NestJS service in the module's logic directory if it exists, else module root. Trigger the NotificationClient:
|
|
127
160
|
|
|
128
161
|
```ts
|
|
129
162
|
import { type NotificationClient } from "@clipboard-health/notifications";
|
|
130
163
|
|
|
131
|
-
import { type
|
|
132
|
-
|
|
133
|
-
type ExampleNotificationDo = ExampleNotificationData["Job"] & { attempt: number };
|
|
164
|
+
import { type ExampleNotificationDo } from "./exampleNotification.constants";
|
|
134
165
|
|
|
135
166
|
export class ExampleNotificationService {
|
|
136
167
|
constructor(private readonly client: NotificationClient) {}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clipboard-health/ai-rules",
|
|
3
3
|
"description": "Pre-built AI agent rules for consistent coding standards.",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.7",
|
|
5
5
|
"bugs": "https://github.com/ClipboardHealth/core-utils/issues",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@intellectronica/ruler": "0.3.17"
|