Repository: carrot-foundation/methodology-rules
Pull request #170: feature/drop off at recycling facility
Author: login: AMarcosCastelo
Labels: name: feature
name: ⏳ Waiting for 2 reviewers
name: 30 min review
name: 🚨 2 Unresolved Thread(s)
Created: 2025-03-20T17:02:08Z | Merged: 2025-03-20T19:18:55Z

- **feat(rule): add DropOffAtRecyclingFacility processor and related tests**
- **feat(rule): set up drop-off-at-recycling-facility rule in bold carbon**
- **feat(rule): set up drop-off-at-recycling-facility rule in bold recycling**

### Summary

- Implemented the DropOffAtRecyclingFacilityProcessor to evaluate drop-off events against recycler events.
- Added end-to-end and unit tests for the new processor to ensure correct functionality.
- Introduced test cases covering various scenarios for drop-off and recycler event validation.
- Updated the index files to export the new processor and its lambda handler.

### Related links

https://www.notion.so/carrot-fndn/Drop-off-at-Recycling-Facility-1b49703d8e9c809d80e4c868fc2eaf4b?pvs=4

---

- [x] **I, the PR author, declare that this PR works as expected and does not break any service. I also declare that I gave my best to apply all of the best practices and that I'm leaving the code better than I found it.**


<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Introduced a new recycling facility drop-off processing capability that enhances event validation and outcome accuracy.
- **Documentation**
	- Added comprehensive usage and contributor information for the new recycling processing feature.
- **Tests**
	- Implemented extensive end-to-end and unit tests to confirm reliable performance.
- **Chores**
	- Streamlined project configurations and quality checks to support the integrated recycling methodologies.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js
new file mode 100644
index 000000000..61e091317
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js
@@ -0,0 +1,7 @@
+const {
+  getBaseEslintConfig,
+} = require('../../../../../../.eslint/eslint.config');
+
+module.exports = getBaseEslintConfig({
+  projectPath: __dirname,
+});
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md
new file mode 100644
index 000000000..d56923c50
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md
@@ -0,0 +1,30 @@
+<div align="center">
+
+# Drop-off At Recycling Facility
+
+Methodology: **BOLD-CARBON-ORGANIC**
+
+[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/carrot-foundation/methodology-rules/check-and-deploy.yaml)](https://github.com/carrot-foundation/smaug/actions)
+
+</div>
+
+## 📄 Description
+
+<!-- TODO: Update README rule descriptions -->
+
+## 📂 Implementation
+
+- **[Main Implementation File](libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts)**
+
+## 👥 Contributors
+
+[![AMarcosCastelo](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/43973049?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/AMarcosCastelo)
+[![andtankian](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/12521890?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/andtankian)
+[![cris-santos](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/7927374?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/cris-santos)
+[![gabrielsl96](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/49005645?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/gabrielsl96)
+[![GLGuilherme](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/26340386?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/GLGuilherme)
+[![sangalli](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/11515359?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/sangalli)
+
+## 🔑 License
+
+[License](https://github.com/carrot-foundation/methodology-rules/blob/main/LICENSE)
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts
new file mode 100644
index 000000000..1e2c108de
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts
@@ -0,0 +1,3 @@
+import { getJestBaseConfig } from '../../../../../../.jest/config/jest.base.config';
+
+export default getJestBaseConfig(__dirname);
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json
new file mode 100644
index 000000000..697f3e731
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json
@@ -0,0 +1,4 @@
+{
+  "name": "@carrot-fndn/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility",
+  "version": "0.0.0"
+}
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json
new file mode 100644
index 000000000..7a0288fcc
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json
@@ -0,0 +1,14 @@
+{
+  "name": "methodologies-bold-carbon-organic-rule-processors-mass-id-drop-off-at-recycling-facility",
+  "$schema": "../../../../../../node_modules/nx/schemas/project-schema.json",
+  "tags": ["methodology:bold", "processor:mass-id", "type:app"],
+  "sourceRoot": "apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src",
+  "projectType": "application",
+  "targets": {
+    "build-lambda": {},
+    "lint": {},
+    "package-lambda": {},
+    "upload-lambda": {},
+    "ts": {}
+  }
+}
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts
new file mode 100644
index 000000000..fd6638665
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts
@@ -0,0 +1 @@
+export { dropOffAtRecyclingFacilityLambda as handler } from '@carrot-fndn/methodologies/bold/rule-processors/mass-id';
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json
new file mode 100644
index 000000000..e9f330757
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json
@@ -0,0 +1,6 @@
+{
+  "extends": [
+    "./tsconfig.json",
+    "../../../../../../.tsconfig/tsconfig.build.json"
+  ]
+}
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json
new file mode 100644
index 000000000..b81b3b862
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json
@@ -0,0 +1,4 @@
+{
+  "extends": "./tsconfig.json",
+  "include": ["**/*.ts"]
+}
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json
new file mode 100644
index 000000000..f8703858b
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json
@@ -0,0 +1,10 @@
+{
+  "extends": "../../../../../../tsconfig.base.json",
+  "files": [],
+  "include": [],
+  "references": [
+    {
+      "path": "./tsconfig.eslint.json"
+    }
+  ]
+}
diff --git a/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json
new file mode 100644
index 000000000..9ae73bfdb
--- /dev/null
+++ b/apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json
@@ -0,0 +1,3 @@
+{
+  "extends": "../../../../../../.tsconfig/tsconfig.spec.json"
+}
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js
new file mode 100644
index 000000000..61e091317
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js
@@ -0,0 +1,7 @@
+const {
+  getBaseEslintConfig,
+} = require('../../../../../../.eslint/eslint.config');
+
+module.exports = getBaseEslintConfig({
+  projectPath: __dirname,
+});
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md
new file mode 100644
index 000000000..afab931a9
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md
@@ -0,0 +1,30 @@
+<div align="center">
+
+# Drop-off At Recycling Facility
+
+Methodology: **BOLD-RECYCLING-ORGANIC**
+
+[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/carrot-foundation/methodology-rules/check-and-deploy.yaml)](https://github.com/carrot-foundation/smaug/actions)
+
+</div>
+
+## 📄 Description
+
+<!-- TODO: Update README rule descriptions -->
+
+## 📂 Implementation
+
+- **[Main Implementation File](libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts)**
+
+## 👥 Contributors
+
+[![AMarcosCastelo](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/43973049?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/AMarcosCastelo)
+[![andtankian](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/12521890?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/andtankian)
+[![cris-santos](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/7927374?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/cris-santos)
+[![gabrielsl96](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/49005645?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/gabrielsl96)
+[![GLGuilherme](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/26340386?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/GLGuilherme)
+[![sangalli](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/11515359?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/sangalli)
+
+## 🔑 License
+
+[License](https://github.com/carrot-foundation/methodology-rules/blob/main/LICENSE)
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts
new file mode 100644
index 000000000..1e2c108de
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts
@@ -0,0 +1,3 @@
+import { getJestBaseConfig } from '../../../../../../.jest/config/jest.base.config';
+
+export default getJestBaseConfig(__dirname);
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json
new file mode 100644
index 000000000..32d29852e
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json
@@ -0,0 +1,4 @@
+{
+  "name": "@carrot-fndn/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility",
+  "version": "0.0.0"
+}
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json
new file mode 100644
index 000000000..77c7a0749
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json
@@ -0,0 +1,14 @@
+{
+  "name": "methodologies-bold-recycling-organic-rule-processors-mass-id-drop-off-at-recycling-facility",
+  "$schema": "../../../../../../node_modules/nx/schemas/project-schema.json",
+  "tags": ["methodology:bold", "processor:mass-id", "type:app"],
+  "sourceRoot": "apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src",
+  "projectType": "application",
+  "targets": {
+    "build-lambda": {},
+    "lint": {},
+    "package-lambda": {},
+    "upload-lambda": {},
+    "ts": {}
+  }
+}
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts
new file mode 100644
index 000000000..fd6638665
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts
@@ -0,0 +1 @@
+export { dropOffAtRecyclingFacilityLambda as handler } from '@carrot-fndn/methodologies/bold/rule-processors/mass-id';
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json
new file mode 100644
index 000000000..e9f330757
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json
@@ -0,0 +1,6 @@
+{
+  "extends": [
+    "./tsconfig.json",
+    "../../../../../../.tsconfig/tsconfig.build.json"
+  ]
+}
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json
new file mode 100644
index 000000000..b81b3b862
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json
@@ -0,0 +1,4 @@
+{
+  "extends": "./tsconfig.json",
+  "include": ["**/*.ts"]
+}
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json
new file mode 100644
index 000000000..f8703858b
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json
@@ -0,0 +1,10 @@
+{
+  "extends": "../../../../../../tsconfig.base.json",
+  "files": [],
+  "include": [],
+  "references": [
+    {
+      "path": "./tsconfig.eslint.json"
+    }
+  ]
+}
diff --git a/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json
new file mode 100644
index 000000000..9ae73bfdb
--- /dev/null
+++ b/apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json
@@ -0,0 +1,3 @@
+{
+  "extends": "../../../../../../.tsconfig/tsconfig.spec.json"
+}
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.e2e.spec.ts b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.e2e.spec.ts
new file mode 100644
index 000000000..f9f87425e
--- /dev/null
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.e2e.spec.ts
@@ -0,0 +1,51 @@
+import { toDocumentKey } from '@carrot-fndn/shared/helpers';
+import { BoldStubsBuilder } from '@carrot-fndn/shared/methodologies/bold/testing';
+import { type RuleOutput } from '@carrot-fndn/shared/rule/types';
+import {
+  prepareEnvironmentTestE2E,
+  stubContext,
+  stubRuleInput,
+  stubRuleResponse,
+} from '@carrot-fndn/shared/testing';
+import { faker } from '@faker-js/faker';
+
+import { dropOffAtRecyclingFacilityLambda } from './drop-off-at-recycling-facility.lambda';
+import { dropOffAtRecyclingFacilityTestCases } from './drop-off-at-recycling-facility.test-cases';
+
+describe('DropOffAtRecyclingFacilityLambda E2E', () => {
+  const documentKeyPrefix = faker.string.uuid();
+
+  it.each(dropOffAtRecyclingFacilityTestCases)(
+    'should return $resultStatus when $scenario',
+    async ({ events, resultComment, resultStatus }) => {
+      const { massIdAuditDocument, massIdDocument } = new BoldStubsBuilder()
+        .createMassIdDocument({
+          externalEventsMap: events,
+        })
+        .createMassIdAuditDocument()
+        .build();
+
+      prepareEnvironmentTestE2E(
+        [massIdAuditDocument, massIdDocument].map((document) => ({
+          document,
+          documentKey: toDocumentKey({
+            documentId: document.id,
+            documentKeyPrefix,
+          }),
+        })),
+      );
+
+      const response = (await dropOffAtRecyclingFacilityLambda(
+        stubRuleInput({
+          documentKeyPrefix,
+          parentDocumentId: massIdDocument.id,
+        }),
+        stubContext(),
+        () => stubRuleResponse(),
+      )) as RuleOutput;
+
+      expect(response.resultComment).toBe(resultComment);
+      expect(response.resultStatus).toBe(resultStatus);
+    },
+  );
+});
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.ts b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.ts
new file mode 100644
index 000000000..7cfeff1eb
--- /dev/null
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.ts
@@ -0,0 +1,8 @@
+import { wrapRuleIntoLambdaHandler } from '@carrot-fndn/shared/lambda/wrapper';
+
+import { DropOffAtRecyclingFacilityProcessor } from './drop-off-at-recycling-facility.processor';
+
+const instance = new DropOffAtRecyclingFacilityProcessor();
+
+export const dropOffAtRecyclingFacilityLambda =
+  wrapRuleIntoLambdaHandler(instance);
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.spec.ts b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.spec.ts
new file mode 100644
index 000000000..919adab35
--- /dev/null
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.spec.ts
@@ -0,0 +1,45 @@
+import { loadParentDocument } from '@carrot-fndn/shared/methodologies/bold/io-helpers';
+import { BoldStubsBuilder } from '@carrot-fndn/shared/methodologies/bold/testing';
+import {
+  type RuleInput,
+  type RuleOutput,
+} from '@carrot-fndn/shared/rule/types';
+import { random } from 'typia';
+
+import { DropOffAtRecyclingFacilityProcessor } from './drop-off-at-recycling-facility.processor';
+import { dropOffAtRecyclingFacilityTestCases } from './drop-off-at-recycling-facility.test-cases';
+
+jest.mock('@carrot-fndn/shared/methodologies/bold/io-helpers');
+
+describe('DropOffAtRecyclingFacilityProcessor', () => {
+  const ruleDataProcessor = new DropOffAtRecyclingFacilityProcessor();
+
+  const documentLoaderService = jest.mocked(loadParentDocument);
+
+  it.each(dropOffAtRecyclingFacilityTestCases)(
+    'should return $resultStatus when $scenario',
+    async ({ events, resultComment, resultStatus }) => {
+      const { massIdDocument } = new BoldStubsBuilder()
+        .createMassIdDocument({
+          externalEventsMap: events,
+        })
+        .build();
+
+      const ruleInput = random<Required<RuleInput>>();
+
+      documentLoaderService.mockResolvedValueOnce(massIdDocument);
+
+      const ruleOutput = await ruleDataProcessor.process(ruleInput);
+
+      const expectedRuleOutput: RuleOutput = {
+        requestId: ruleInput.requestId,
+        responseToken: ruleInput.responseToken,
+        responseUrl: ruleInput.responseUrl,
+        resultComment,
+        resultStatus,
+      };
+
+      expect(ruleOutput).toEqual(expectedRuleOutput);
+    },
+  );
+});
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
new file mode 100644
index 000000000..425bb63af
--- /dev/null
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
@@ -0,0 +1,93 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    return {
+      resultComment: RESULT_COMMENTS.APPROVED,
+      resultStatus: RuleOutputStatus.APPROVED,
+    };
+  }
+
+  protected override getRuleSubject(document: Document): RuleSubject {
+    const recyclerEvent = document.externalEvents?.find(
+      and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
+    );
+    const lastDropOffEvent = document.externalEvents
+      ?.filter(eventNameIsAnyOf([DROP_OFF]))
+      .at(-1);
+
+    return {
+      lastDropOffEvent,
+      receivingOperatorIdentifier: getEventAttributeValue(
+        lastDropOffEvent,
+        RECEIVING_OPERATOR_IDENTIFIER,
+      ),
+      recyclerEvent,
+    };
+  }
+}
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts
new file mode 100644
index 000000000..2ab6402c6
--- /dev/null
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts
@@ -0,0 +1,63 @@
+import {
+  stubAddress,
+  stubBoldMassIdDropOffEvent,
+  stubDocumentEvent,
+} from '@carrot-fndn/shared/methodologies/bold/testing';
+import {
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import { MethodologyDocumentEventLabel } from '@carrot-fndn/shared/types';
+
+import { RESULT_COMMENTS } from './drop-off-at-recycling-facility.processor';
+
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+const sameRecyclerAndDropOffAddress = stubAddress();
+
+export const dropOffAtRecyclingFacilityTestCases = [
+  {
+    events: { [DROP_OFF]: undefined },
+    resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+    resultStatus: RuleOutputStatus.REJECTED,
+    scenario: `the MassID document has no ${DROP_OFF} event`,
+  },
+  {
+    events: {
+      [DROP_OFF]: stubBoldMassIdDropOffEvent({
+        metadataAttributes: [[RECEIVING_OPERATOR_IDENTIFIER, undefined]],
+      }),
+    },
+    resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+    resultStatus: RuleOutputStatus.REJECTED,
+    scenario: `the MassID document has a ${DROP_OFF} event but no ${RECEIVING_OPERATOR_IDENTIFIER} attribute`,
+  },
+  {
+    events: {
+      [DROP_OFF]: stubBoldMassIdDropOffEvent(),
+    },
+    resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+    resultStatus: RuleOutputStatus.REJECTED,
+    scenario: `the MassID document has a ${DROP_OFF} event, but the ${RECYCLER} event address does not match the ${DROP_OFF} event address`,
+  },
+  {
+    events: {
+      [`${ACTOR}-${RECYCLER}`]: stubDocumentEvent({
+        address: sameRecyclerAndDropOffAddress,
+        label: RECYCLER,
+        name: ACTOR,
+      }),
+      [DROP_OFF]: stubBoldMassIdDropOffEvent({
+        partialDocumentEvent: {
+          address: sameRecyclerAndDropOffAddress,
+        },
+      }),
+    },
+    resultComment: RESULT_COMMENTS.APPROVED,
+    resultStatus: RuleOutputStatus.APPROVED,
+    scenario: `the MassID document has a ${DROP_OFF} event and a ${RECYCLER} event, and the ${DROP_OFF} event address matches the ${RECYCLER} event address`,
+  },
+];
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/index.ts b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/index.ts
new file mode 100644
index 000000000..d79bf3ba8
--- /dev/null
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/index.ts
@@ -0,0 +1 @@
+export * from './drop-off-at-recycling-facility.lambda';
diff --git a/libs/methodologies/bold/rule-processors/mass-id/src/index.ts b/libs/methodologies/bold/rule-processors/mass-id/src/index.ts
index 2947b01db..c7698909f 100644
--- a/libs/methodologies/bold/rule-processors/mass-id/src/index.ts
+++ b/libs/methodologies/bold/rule-processors/mass-id/src/index.ts
@@ -11,3 +11,4 @@ export * from './geolocation-precision';
 export * from './driver-identification';
 export * from './local-waste-classification';
 export * from './processor-identification';
+export * from './drop-off-at-recycling-facility';
diff --git a/libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts b/libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts
index a7a8fe52a..2c959e1e8 100644
--- a/libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts
+++ b/libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts
@@ -64,6 +64,7 @@ const {
   LOCAL_WASTE_CLASSIFICATION_DESC,
   LOCAL_WASTE_CLASSIFICATION_ID,
   MASS_NET_WEIGHT,
+  RECEIVING_OPERATOR_IDENTIFIER,
   RECYCLER_OPERATOR_IDENTIFIER,
   SCALE_HOMOLOGATION,
   SCALE_TYPE,
@@ -185,6 +186,7 @@ export const stubBoldMassIdWeighingSingleStepEvent = ({
   );
 
 const defaultDropOffAttributes: MetadataAttributeParameter[] = [
+  [RECEIVING_OPERATOR_IDENTIFIER, faker.string.uuid()],
   [RECYCLER_OPERATOR_IDENTIFIER, faker.string.uuid()],
   [DESCRIPTION, faker.lorem.sentence()],
   [CAPTURED_GPS_LATITUDE, faker.location.latitude()],
diff --git a/libs/shared/methodologies/bold/types/src/enum.types.ts b/libs/shared/methodologies/bold/types/src/enum.types.ts
index e2769769d..7a0ad990b 100644
--- a/libs/shared/methodologies/bold/types/src/enum.types.ts
+++ b/libs/shared/methodologies/bold/types/src/enum.types.ts
@@ -101,6 +101,7 @@ export enum NewDocumentEventAttributeName {
   LOCAL_WASTE_CLASSIFICATION_DESC = 'Local Waste Classification Desc',
   LOCAL_WASTE_CLASSIFICATION_ID = 'Local Waste Classification ID',
   MASS_NET_WEIGHT = 'Mass Net Weight',
+  RECEIVING_OPERATOR_IDENTIFIER = 'Receiving Operator Identifier',
   RECYCLER_OPERATOR_IDENTIFIER = 'Recycler Operator Identifier',
   SCALE_HOMOLOGATION = 'Scale Homologation',
   SCALE_TYPE = 'Scale Type',


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json (1)</summary><blockquote>

`1-4`: **Package configuration is minimal but sufficient**

The package.json correctly defines the module name and version. While the file is minimal, it provides the essential information required to identify the package within the repository.


Consider adding additional fields like `description`, `private: true`, and potentially any specific dependencies this module requires. This would improve documentation and make the package configuration more robust.

</blockquote></details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts (1)</summary><blockquote>

`1-20`: **Consider adding test for multiple recycler events.**

I noticed that in the `RESULT_COMMENTS` object from the processor file, there's a constant for `MULTIPLE_RECYCLER_EVENTS`, but there's no test case that covers this scenario. If the processor needs to handle multiple recycler events, consider adding a test case for this scenario.

```diff
+  {
+    events: {
+      [`${ACTOR}-${RECYCLER}-1`]: stubDocumentEvent({
+        address: sameRecyclerAndDropOffAddress,
+        label: RECYCLER,
+        name: ACTOR,
+      }),
+      [`${ACTOR}-${RECYCLER}-2`]: stubDocumentEvent({
+        address: stubAddress(),
+        label: RECYCLER,
+        name: ACTOR,
+      }),
+      [DROP_OFF]: stubBoldMassIdDropOffEvent(),
+    },
+    resultComment: RESULT_COMMENTS.MULTIPLE_RECYCLER_EVENTS,
+    resultStatus: RuleOutputStatus.REJECTED,
+    scenario: `the MassID document has multiple ${RECYCLER} events`,
+  },
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 2f102ceb650735edfed217e7ae538fca273dcf82 and b6d4fd66ccaa50cf3637dcedc91261854a2a6ad6.

</details>

<details>
<summary>📒 Files selected for processing (29)</summary>

* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json` (1 hunks)
* `apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json` (1 hunks)
* `apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.e2e.spec.ts` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.ts` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.spec.ts` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/index.ts` (1 hunks)
* `libs/methodologies/bold/rule-processors/mass-id/src/index.ts` (1 hunks)
* `libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts` (2 hunks)
* `libs/shared/methodologies/bold/types/src/enum.types.ts` (1 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Definitions (3)</summary>

<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts (2)</summary><blockquote>

<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts (1) (1)</summary>

* `RESULT_COMMENTS` (27-33)

</details>
<details>
<summary>libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts (1) (1)</summary>

* `stubBoldMassIdDropOffEvent` (196-206)

</details>

</blockquote></details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.spec.ts (2)</summary><blockquote>

<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts (1) (1)</summary>

* `DropOffAtRecyclingFacilityProcessor` (44-94)

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts (1) (1)</summary>

* `dropOffAtRecyclingFacilityTestCases` (21-63)

</details>

</blockquote></details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.ts (1)</summary><blockquote>

<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts (1) (1)</summary>

* `DropOffAtRecyclingFacilityProcessor` (44-94)

</details>

</blockquote></details>

</details><details>
<summary>🪛 LanguageTool</summary>

<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md</summary>

[style] ~21-~21: Using many exclamation marks might seem excessive (in this case: 4 exclamation marks for a text that’s 842 characters long)
Context: ...7d)](https://github.com/AMarcosCastelo) [![andtankian](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/12521890?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/andtankian) [![cris-santos](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/7927374?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/cris-santos) [![gabrielsl96](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/49005645?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/gabrielsl96) [![GLGuilherme](https://images.weserv.nl/?...

(EN_EXCESSIVE_EXCLAMATION)

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md</summary>

[style] ~21-~21: Using many exclamation marks might seem excessive (in this case: 4 exclamation marks for a text that’s 845 characters long)
Context: ...7d)](https://github.com/AMarcosCastelo) [![andtankian](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/12521890?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/andtankian) [![cris-santos](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/7927374?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/cris-santos) [![gabrielsl96](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/49005645?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/gabrielsl96) [![GLGuilherme](https://images.weserv.nl/?...

(EN_EXCESSIVE_EXCLAMATION)

</details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (5)</summary>

* GitHub Check: Backend Check / Tests
* GitHub Check: Backend Check / ESLint
* GitHub Check: Backend Check / TypeScript
* GitHub Check: gitStream.cm
* GitHub Check: gitStream.cm

</details>

<details>
<summary>🔇 Additional comments (30)</summary><blockquote>

<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json (1)</summary>

`1-4`: **Configuration looks good for ESLint integration**

The TypeScript ESLint configuration extends the base tsconfig and correctly includes all TypeScript files in the project directory, which is the standard approach for ESLint configuration files.

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/index.ts (1)</summary>

`14-14`: **Export of the new drop-off facility module looks good**

The new export follows the established pattern in this file and makes the drop-off-at-recycling-facility functionality available to consumers of this package. This change aligns well with the PR objective of introducing the new processor.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.eslint.json (1)</summary>

`1-4`: **Configuration looks good for ESLint integration**

This ESLint configuration file correctly extends the base tsconfig and includes all TypeScript files for linting, maintaining consistency with the equivalent configuration in the bold-recycling-organic methodology.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json (1)</summary>

`1-3`: **Configuration Inheritance is Correct**

The file properly extends the base TypeScript spec configuration from the relative path. Please double-check that the relative path (`../../../../../../.tsconfig/tsconfig.spec.json`) remains valid in your project structure.

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/index.ts (1)</summary>

`1-2`: **Re-export Strategy Verified**

This file re-exports all public entities from the Lambda module cleanly. It centralizes the export for easier consumption by other parts of the system.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/package.json (1)</summary>

`1-4`: **Minimal Package Configuration Check**

The package name and version are defined as intended. While version `"0.0.0"` is typical for early stages or experimental modules, please ensure that versioning is updated before any production releases.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.spec.json (1)</summary>

`1-3`: **Consistent TypeScript Spec Extension**

This configuration file mirrors the structure used in the bold-carbon-organic module by extending the shared base configuration. Ensure that the relative path is still valid for this module context.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts (1)</summary>

`1-4`: **Jest Configuration is Appropriately Set Up**

The file imports the base Jest configuration and exports it using `__dirname`, ensuring that tests within this module follow the standardized settings. Confirm that the relative path to the base config (`../../../../../../.jest/config/jest.base.config`) resolves correctly in your environment.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/jest.config.ts (1)</summary>

`1-3`: **Jest Configuration Looks Good!**  
The file correctly imports the base Jest configuration from the specified path and then directly exports it using the current directory context. Please ensure that the relative path remains valid if the directory structure changes in the future.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json (1)</summary>

`1-7`: **TypeScript Build Config is Correctly Set Up.**  
This configuration extends both the local `tsconfig.json` and a global build configuration. The structure is clear and supports a consolidated TS setup. Double-check that the relative path (`../../../../../../.tsconfig/tsconfig.build.json`) is accurate relative to this file’s location.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.build.json (1)</summary>

`1-7`: **Consistent TS Build Configuration.**  
The file mirrors the approach used in the bold-carbon-organic directory, extending both the local config and a global build config. As before, please verify that the relative path to the global configuration is correct, ensuring consistency across the project.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts (1)</summary>

`1-2`: **Lambda Export is Clean and Concise.**  
The file re-exports `dropOffAtRecyclingFacilityLambda` as `handler` from the centralized module. This pattern is effective for exposing the new functionality as the Lambda entry point. Just ensure that the namespace `@carrot-fndn/methodologies/bold/rule-processors/mass-id` consistently provides the expected exports across environments.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/src/lambda.ts (1)</summary>

`1-2`: **Appropriate Lambda Handler Re-export.**  
This export statement correctly provides the Lambda handler by re-exporting `dropOffAtRecyclingFacilityLambda` as `handler`. Verify that the referenced module is structured to support both Bold Carbon and Bold Recycling scenarios as intended.

</details>
<details>
<summary>libs/shared/methodologies/bold/types/src/enum.types.ts (1)</summary>

`104-104`: **LGTM: This new enum value aligns with the recycling facility feature.**

The addition of `RECEIVING_OPERATOR_IDENTIFIER` to the `NewDocumentEventAttributeName` enum is well-structured and follows the existing naming conventions. This properly supports the new drop-off at recycling facility functionality described in the PR objectives.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js (1)</summary>

`1-7`: **LGTM: ESLint config follows project conventions.**

The ESLint configuration imports the base config correctly and follows the project's established pattern for rule processor modules.

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.ts (1)</summary>

`1-8`: **LGTM: Lambda handler properly implements the singleton pattern.**

The implementation correctly creates a single instance of the processor and wraps it as a Lambda handler, following the project's established patterns for Lambda function exports.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/.eslintrc.js (1)</summary>

`1-7`: **LGTM: ESLint config follows project conventions.**

The ESLint configuration for the bold-recycling-organic methodology correctly imports the base config and follows the same pattern as the bold-carbon-organic implementation, ensuring consistency across methodologies.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md (1)</summary>

`13-13`: **Complete the README description section.**

The TODO comment indicates that the rule descriptions need to be updated. Make sure to provide a clear and comprehensive description of the "Drop-off At Recycling Facility" rule and its purpose within the BOLD-RECYCLING-ORGANIC methodology.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json (1)</summary>

`7-13`: **LGTM: Project configuration structure is correct.**

The project configuration follows the expected structure for NX projects with appropriate tags and empty target configurations that will likely be populated during the build process.

</details>
<details>
<summary>apps/methodologies/bold-recycling-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json (1)</summary>

`1-10`: **LGTM: TypeScript configuration is properly structured.**

The TypeScript configuration correctly extends the base configuration and references the eslint configuration file.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/project.json (1)</summary>

`1-14`: **LGTM: Project configuration structure is correct.**

The project configuration follows the expected structure for NX projects with appropriate tags and empty target configurations.

</details>
<details>
<summary>libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts (1)</summary>

`67-67`: **LGTM: Successfully added receiving operator identifier.**

The `RECEIVING_OPERATOR_IDENTIFIER` constant is appropriately added to the import list and correctly incorporated into the `defaultDropOffAttributes` array, ensuring proper test stub generation for drop-off events.



Also applies to: 189-189

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/tsconfig.json (1)</summary>

`1-10`: **TypeScript configuration looks good!**

The configuration correctly extends the base TypeScript config and references the eslint configuration file. This follows the project's standard structure for TypeScript configuration files.

</details>
<details>
<summary>apps/methodologies/bold-carbon-organic/rule-processors/mass-id/drop-off-at-recycling-facility/README.md (2)</summary>

`13-13`: **TODO item needs to be addressed.**

The README contains a TODO comment to update the rule descriptions. This should be completed before finalizing the PR to provide proper documentation about this rule processor.

Please update the rule description in the README to explain what the "Drop-off At Recycling Facility" rule does and its purpose in the methodology.

---

`1-30`: **Good README structure.**

The README provides a well-structured documentation of the module, including methodology context, implementation reference, contributors, and license information.

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 LanguageTool</summary>

[style] ~21-~21: Using many exclamation marks might seem excessive (in this case: 4 exclamation marks for a text that’s 842 characters long)
Context: ...7d)](https://github.com/AMarcosCastelo) [![andtankian](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/12521890?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/andtankian) [![cris-santos](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/7927374?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/cris-santos) [![gabrielsl96](https://images.weserv.nl/?url=avatars.githubusercontent.com/u/49005645?v=4&h=60&w=60&fit=cover&mask=circle&maxage=7d)](https://github.com/gabrielsl96) [![GLGuilherme](https://images.weserv.nl/?...

(EN_EXCESSIVE_EXCLAMATION)

</details>

</details>

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.spec.ts (1)</summary>

`1-45`: **Test implementation is comprehensive.**

The test suite correctly covers all scenarios defined in the test cases file. It properly mocks the document loader service and validates the processor's output against expected results.

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.test-cases.ts (1)</summary>

`21-63`: **Test cases are well-defined.**

The test cases cover the essential scenarios for the rule processor:
- Missing drop-off event
- Missing receiving operator identifier
- Address mismatch
- Successful match with proper addressing

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.lambda.e2e.spec.ts (1)</summary>

`1-51`: **Well-structured E2E test suite.**

The test file is well-organized and follows good testing practices:
- Uses appropriate test utilities and stubs
- Leverages parameterized testing with `it.each`
- Creates necessary test fixtures with `BoldStubsBuilder`
- Makes clear assertions against expected outcomes

This approach ensures comprehensive coverage of the different scenarios for the drop-off-at-recycling-facility rule.

</details>
<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts (2)</summary>

`27-33`: **Clear and descriptive result messages.**

The result comments are well-defined, descriptive, and use template literals to maintain consistency when referencing constants. This makes error messages more understandable and maintainable.

---

`44-75`: **Well-structured evaluation logic.**

The `evaluateResult` method follows a clear pattern of validation checks, with early returns for rejection cases. This approach makes the code easy to follow and maintain.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-20T17:08:34Z
user: login: cris-santos
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T17:58:16Z
user: login: AMarcosCastelo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T19:15:14Z
user: login: AMarcosCastelo
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-20T19:15:35Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-20T19:15:38Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-20T19:15:58Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts (1)</summary><blockquote>

`27-33`: **Consider adding result comments for missing or multiple recycler events.**
Although you have constants for drop-off event errors, you do not have result comments for missing or multiple recycler events. This would keep error handling consistent.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: .coderabbit.yaml**
**Review profile: CHILL**
**Plan: Lite**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between b6d4fd66ccaa50cf3637dcedc91261854a2a6ad6 and b4d2caeab1072ded6b3eba4d68d06cf8d965d9a4.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts` (1 hunks)

</details>

<details>
<summary>🔇 Additional comments (5)</summary><blockquote>

<details>
<summary>libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts (5)</summary>

`1-2`: **No concerns on import statements.**

---

`3-23`: **No issues noted with these imports.**

---

`34-42`: **Interface definition looks good.**

---

`63-68`: **Add null check for recyclerEvent.**


According to a previous review recommendation, the code needs explicit handling when `recyclerEvent` is undefined. You can return a dedicated result comment and status for this scenario:

```diff
+    if (isNil(recyclerEvent)) {
+      return {
+        resultComment: 'No recycler event was found in the document.',
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }

     if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
       return {
         resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
         resultStatus: RuleOutputStatus.REJECTED,
       };
     }
```

---

`76-93`: **Add validation for multiple recycler events.**


From a previous review suggestion, if multiple recycler events are present, log or return a more specific result comment. For example:

```diff
  protected override getRuleSubject(document: Document): RuleSubject {
+    const recyclerEvents = document.externalEvents?.filter(
+      and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
+    );

+    if (recyclerEvents && recyclerEvents.length > 1) {
+      // Log or handle multiple recycler events scenario
+      // e.g., record in resultComment or in logs
+    }

     const recyclerEvent = recyclerEvents?.[0];
     const lastDropOffEvent = ...
```

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-03-20T19:16:17Z

Review comments:
diff_hunk: @@ -0,0 +1,94 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+  MULTIPLE_RECYCLER_EVENTS: `More than one "${RECYCLER}" event was found, but only one is allowed.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
path: libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add null check for recyclerEvent.**

Although you're using optional chaining for `recyclerEvent?.address.id`, there's no dedicated handling for the case when `recyclerEvent` is undefined. According to your result comments, you have a message for "MULTIPLE_RECYCLER_EVENTS" but not for "MISSING_RECYCLER_EVENT".


```diff
-    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+    if (isNil(recyclerEvent)) {
+      return {
+        resultComment: 'No recycler event was found in the document.',
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent.address.id) {
       return {
         resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
         resultStatus: RuleOutputStatus.REJECTED,
       };
     }
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
    if (isNil(recyclerEvent)) {
      return {
        resultComment: 'No recycler event was found in the document.',
        resultStatus: RuleOutputStatus.REJECTED,
      };
    }

    if (lastDropOffEvent.address.id !== recyclerEvent.address.id) {
      return {
        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
        resultStatus: RuleOutputStatus.REJECTED,
      };
    }
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-20T17:08:33Z
author_association: NONE
diff_hunk: @@ -0,0 +1,94 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+  MULTIPLE_RECYCLER_EVENTS: `More than one "${RECYCLER}" event was found, but only one is allowed.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    return {
+      resultComment: RESULT_COMMENTS.APPROVED,
+      resultStatus: RuleOutputStatus.APPROVED,
+    };
+  }
+
+  protected override getRuleSubject(document: Document): RuleSubject {
+    const recyclerEvent = document.externalEvents?.find(
+      and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
+    );
+    const lastDropOffEvent = document.externalEvents
+      ?.filter(eventNameIsAnyOf([DROP_OFF]))
+      .at(-1);
+
+    return {
+      lastDropOffEvent,
+      receivingOperatorIdentifier: getEventAttributeValue(
+        lastDropOffEvent,
+        RECEIVING_OPERATOR_IDENTIFIER,
+      ),
+      recyclerEvent,
+    };
+  }
+}
path: libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**Add validation for multiple recycler events.**

You have a result comment for "MULTIPLE_RECYCLER_EVENTS" in your constants, but the code doesn't check for this condition. Consider adding validation to handle this case.


```diff
  protected override getRuleSubject(document: Document): RuleSubject {
-    const recyclerEvent = document.externalEvents?.find(
+    const recyclerEvents = document.externalEvents?.filter(
       and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
     );
+
+    const recyclerEvent = recyclerEvents?.length === 1 
+      ? recyclerEvents[0] 
+      : (recyclerEvents?.length ? undefined : undefined);
+
+    // Handle multiple recycler events scenario
+    if (recyclerEvents?.length > 1) {
+      this.logger.warn('Multiple recycler events found in document', {
+        documentId: document.id,
+        recyclerEventsCount: recyclerEvents.length,
+      });
+    }
+
     const lastDropOffEvent = document.externalEvents
       ?.filter(eventNameIsAnyOf([DROP_OFF]))
       .at(-1);

     return {
       lastDropOffEvent,
       receivingOperatorIdentifier: getEventAttributeValue(
         lastDropOffEvent,
         RECEIVING_OPERATOR_IDENTIFIER,
       ),
       recyclerEvent,
     };
   }
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
  protected override getRuleSubject(document: Document): RuleSubject {
    const recyclerEvents = document.externalEvents?.filter(
      and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
    );

    const recyclerEvent = recyclerEvents?.length === 1 
      ? recyclerEvents[0] 
      : (recyclerEvents?.length ? undefined : undefined);

    // Handle multiple recycler events scenario
    if (recyclerEvents?.length > 1) {
      this.logger.warn('Multiple recycler events found in document', {
        documentId: document.id,
        recyclerEventsCount: recyclerEvents.length,
      });
    }

    const lastDropOffEvent = document.externalEvents
      ?.filter(eventNameIsAnyOf([DROP_OFF]))
      .at(-1);

    return {
      lastDropOffEvent,
      receivingOperatorIdentifier: getEventAttributeValue(
        lastDropOffEvent,
        RECEIVING_OPERATOR_IDENTIFIER,
      ),
      recyclerEvent,
    };
  }
}
`````

</details>

<!-- suggestion_end -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-20T17:08:33Z
author_association: NONE
diff_hunk: @@ -0,0 +1,94 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+  MULTIPLE_RECYCLER_EVENTS: `More than one "${RECYCLER}" event was found, but only one is allowed.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    return {
+      resultComment: RESULT_COMMENTS.APPROVED,
+      resultStatus: RuleOutputStatus.APPROVED,
+    };
+  }
+
+  protected override getRuleSubject(document: Document): RuleSubject {
+    const recyclerEvent = document.externalEvents?.find(
+      and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
+    );
+    const lastDropOffEvent = document.externalEvents
+      ?.filter(eventNameIsAnyOf([DROP_OFF]))
+      .at(-1);
+
+    return {
+      lastDropOffEvent,
+      receivingOperatorIdentifier: getEventAttributeValue(
+        lastDropOffEvent,
+        RECEIVING_OPERATOR_IDENTIFIER,
+      ),
+      recyclerEvent,
+    };
+  }
+}
path: libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
user: login: AMarcosCastelo
body: [feature/drop-off-at-recycling-facilitu b4d2cae] refactor(rule): remove MULTIPLE_RECYCLER_EVENTS comment from rule
created_at: 2025-03-20T19:15:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,94 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+  MULTIPLE_RECYCLER_EVENTS: `More than one "${RECYCLER}" event was found, but only one is allowed.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
path: libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
user: login: AMarcosCastelo
body: [feature/drop-off-at-recycling-facilitu b4d2cae] refactor(rule): remove MULTIPLE_RECYCLER_EVENTS comment from rule
created_at: 2025-03-20T19:15:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,94 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+  MULTIPLE_RECYCLER_EVENTS: `More than one "${RECYCLER}" event was found, but only one is allowed.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    return {
+      resultComment: RESULT_COMMENTS.APPROVED,
+      resultStatus: RuleOutputStatus.APPROVED,
+    };
+  }
+
+  protected override getRuleSubject(document: Document): RuleSubject {
+    const recyclerEvent = document.externalEvents?.find(
+      and(eventLabelIsAnyOf([RECYCLER]), eventNameIsAnyOf([ACTOR])),
+    );
+    const lastDropOffEvent = document.externalEvents
+      ?.filter(eventNameIsAnyOf([DROP_OFF]))
+      .at(-1);
+
+    return {
+      lastDropOffEvent,
+      receivingOperatorIdentifier: getEventAttributeValue(
+        lastDropOffEvent,
+        RECEIVING_OPERATOR_IDENTIFIER,
+      ),
+      recyclerEvent,
+    };
+  }
+}
path: libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
user: login: coderabbitai[bot]
body: @AMarcosCastelo Thanks for addressing the inconsistency by removing the unused MULTIPLE_RECYCLER_EVENTS comment. This is a clean solution that keeps the code focused on the current requirements.

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-20T19:15:38Z
author_association: NONE
diff_hunk: @@ -0,0 +1,94 @@
+import type { EvaluateResultOutput } from '@carrot-fndn/shared/rule/standard-data-processor';
+
+import { isNil, isNonEmptyString } from '@carrot-fndn/shared/helpers';
+import { getEventAttributeValue } from '@carrot-fndn/shared/methodologies/bold/getters';
+import {
+  and,
+  eventLabelIsAnyOf,
+  eventNameIsAnyOf,
+} from '@carrot-fndn/shared/methodologies/bold/predicates';
+import { ParentDocumentRuleProcessor } from '@carrot-fndn/shared/methodologies/bold/processors';
+import {
+  type Document,
+  type DocumentEvent,
+  DocumentEventName,
+  NewDocumentEventAttributeName,
+} from '@carrot-fndn/shared/methodologies/bold/types';
+import { RuleOutputStatus } from '@carrot-fndn/shared/rule/types';
+import {
+  type MethodologyDocumentEventAttributeValue,
+  MethodologyDocumentEventLabel,
+} from '@carrot-fndn/shared/types';
+
+const { ACTOR, DROP_OFF } = DocumentEventName;
+const { RECYCLER } = MethodologyDocumentEventLabel;
+const { RECEIVING_OPERATOR_IDENTIFIER } = NewDocumentEventAttributeName;
+
+export const RESULT_COMMENTS = {
+  ADDRESS_MISMATCH: `The "${DROP_OFF}" event address does not match the "${RECYCLER}" event address.`,
+  APPROVED: `The "${DROP_OFF}" event was recorded with a valid "${RECEIVING_OPERATOR_IDENTIFIER}", and its address matches the "${RECYCLER}" event address.`,
+  MISSING_DROP_OFF_EVENT: `No "${DROP_OFF}" event was found in the document.`,
+  MISSING_RECEIVING_OPERATOR_IDENTIFIER: `The "${DROP_OFF}" event must include a "${RECEIVING_OPERATOR_IDENTIFIER}", but none was provided.`,
+  MULTIPLE_RECYCLER_EVENTS: `More than one "${RECYCLER}" event was found, but only one is allowed.`,
+} as const;
+
+interface RuleSubject {
+  lastDropOffEvent: DocumentEvent | undefined;
+  receivingOperatorIdentifier:
+    | MethodologyDocumentEventAttributeValue
+    | string
+    | undefined;
+  recyclerEvent: DocumentEvent | undefined;
+}
+
+export class DropOffAtRecyclingFacilityProcessor extends ParentDocumentRuleProcessor<RuleSubject> {
+  protected override evaluateResult({
+    lastDropOffEvent,
+    receivingOperatorIdentifier,
+    recyclerEvent,
+  }: RuleSubject): EvaluateResultOutput | Promise<EvaluateResultOutput> {
+    if (isNil(lastDropOffEvent)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_DROP_OFF_EVENT,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (!isNonEmptyString(receivingOperatorIdentifier)) {
+      return {
+        resultComment: RESULT_COMMENTS.MISSING_RECEIVING_OPERATOR_IDENTIFIER,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
+    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+      return {
+        resultComment: RESULT_COMMENTS.ADDRESS_MISMATCH,
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
path: libs/methodologies/bold/rule-processors/mass-id/src/drop-off-at-recycling-facility/drop-off-at-recycling-facility.processor.ts
user: login: coderabbitai[bot]
body: @AMarcosCastelo Good call on removing the unused MULTIPLE_RECYCLER_EVENTS comment! 

However, we still need to handle the case when `recyclerEvent` is undefined. Consider adding a null check before comparing addresses:

```diff
+    if (isNil(recyclerEvent)) {
+      return {
+        resultComment: 'No recycler event was found in the document.',
+        resultStatus: RuleOutputStatus.REJECTED,
+      };
+    }
+
-    if (lastDropOffEvent.address.id !== recyclerEvent?.address.id) {
+    if (lastDropOffEvent.address.id !== recyclerEvent.address.id) {
```

You might also want to add this message to your RESULT_COMMENTS object for consistency.

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-20T19:15:58Z
author_association: NONE

PR comments:
user: login: gitstream-cm[bot]
created_at: 2025-03-20T17:02:11Z
body: 
🚨 **gitStream Monthly Automation Limit Reached** 🚨

Your organization has exceeded the number of pull requests allowed for automation with gitStream.
**Monthly PRs automated:** 463/250

To continue automating your PR workflows and unlock additional features, please [contact LinearB](https://linearb.io/book-a-demo).

author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-03-20T17:02:16Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
This pull request introduces a complete set of new files for the drop-off at recycling facility feature under two methodologies: bold-carbon-organic and bold-recycling-organic. The changes include ESLint and Jest configuration files, README documents, package and project configuration files, multiple TypeScript configuration files, Lambda handler exports, and test suites. Additionally, new processor logic, re-exports, and shared constants are added to ensure consistent rule processing and testing.

## Changes

| File(s) | Change Summary |
|---------|----------------|
| `apps/.../drop-off-at-recycling-facility/.eslintrc.js` (both bold-carbon-organic & bold-recycling-organic) | Added ESLint configuration files importing a base config using `getBaseEslintConfig`. |
| `apps/.../drop-off-at-recycling-facility/README.md` (both) | New README files with a title, description, implementation link, contributor details, and license section. |
| `apps/.../drop-off-at-recycling-facility/jest.config.ts` (both) | Introduced Jest configuration files that import and export base Jest settings. |
| `apps/.../drop-off-at-recycling-facility/package.json` (both) | New package definition files setting the module name and version to "0.0.0". |
| `apps/.../drop-off-at-recycling-facility/project.json` (both) | Added project configuration files defining metadata, source roots, and build/deployment targets. |
| `apps/.../drop-off-at-recycling-facility/src/lambda.ts` (both) | Exported `dropOffAtRecyclingFacilityLambda` as the Lambda handler from the shared module. |
| `apps/.../drop-off-at-recycling-facility/tsconfig.*.json` (both) | New TypeScript configuration files (build, eslint, main, spec) extending from base configurations. |
| `libs/.../drop-off-at-recycling-facility/*` | Added new Lambda file, processor class (`DropOffAtRecyclingFacilityProcessor`), test suites (E2E and unit tests), test cases, and index re-exports for drop-off functionality. |
| `libs/shared/methodologies/bold/*` | Added the `RECEIVING_OPERATOR_IDENTIFIER` constant to stubs and as a new enum value in the shared types. |

## Sequence Diagram(s)
```mermaid
sequenceDiagram
    participant Client
    participant Lambda as dropOffAtRecyclingFacilityLambda
    participant Processor as DropOffAtRecyclingFacilityProcessor
    Client->>Lambda: Invoke with event data
    Lambda->>Processor: Extract rule subject and evaluate
    Processor-->>Lambda: Return evaluation result (approval/rejection)
    Lambda-->>Client: Send response with result details
```

## Possibly related PRs
- **carrot-foundation/methodology-rules#123**: Updates to ESLint configurations affecting the project structure.
- **carrot-foundation/methodology-rules#124**: Modifications introducing new ESLint configurations based on the same base function.

## Suggested labels
`30 min review`

## Suggested reviewers
- cris-santos
- sangalli

## Poem
> I’m a happy little rabbit, hopping through the code,  
> New files and configs in every mode.  
> Lambdas and tests, all in a row,  
> Dropping off recycling, watch the processor go!  
> With carrots in hand, I celebrate this ode.  
> 🥕✨ Happy coding!

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=carrot-foundation/methodology-rules&utm_content=170):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: gitstream-cm[bot]
created_at: 2025-03-20T17:03:34Z
body: 🥷 **Code experts: no user but you matched threshold 10** 
 
AMarcosCastelo has most 👩‍💻 **activity** in the files. 
AMarcosCastelo has most 🧠 **knowledge** in the files. 
 <details>
 <summary>See details</summary>


`libs/methodologies/bold/rule-processors/mass-id/src/index.ts` 
 

Activity based on git-commit: 

 |  | AMarcosCastelo |  
 | --- | --- | 
| MAR | 14 additions & 4 deletions |  
| FEB | 4 additions & 1 deletions |  
| JAN |   |  
| DEC |   |  
| NOV |   |  
| OCT |   |  
 

Knowledge based on git-blame: 
 AMarcosCastelo: 100% 

`libs/shared/methodologies/bold/testing/src/builders/bold-mass-id.stubs.ts` 
 

Activity based on git-commit: 

 |  | AMarcosCastelo |  
 | --- | --- | 
| MAR | 326 additions & 20 deletions |  
| FEB |   |  
| JAN |   |  
| DEC |   |  
| NOV |   |  
| OCT |   |  
 

Knowledge based on git-blame: 
 AMarcosCastelo: 100% 

`libs/shared/methodologies/bold/types/src/enum.types.ts` 
 

Activity based on git-commit: 

 |  | AMarcosCastelo |  
 | --- | --- | 
| MAR | 87 additions & 2 deletions |  
| FEB | 184 additions & 0 deletions |  
| JAN |   |  
| DEC |   |  
| NOV |   |  
| OCT |   |  
 

Knowledge based on git-blame: 
 AMarcosCastelo: 98% 

</details>
 
 
 
 
To learn more about /:\ gitStream - [Visit our Docs](https://docs.gitstream.cm/) 
 
 

<automation id="gitstream/explain_code_experts"/>
author_association: NONE
user: login: gitstream-cm[bot]
created_at: 2025-03-20T17:03:45Z
body: This PR is 100% new code.

<automation id="gitstream/percent_new_code"/>
author_association: NONE
user: login: sonarqubecloud[bot]
created_at: 2025-03-20T19:15:39Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=carrot-foundation_audit-rules&pullRequest=170) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=carrot-foundation_audit-rules&pullRequest=170&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=carrot-foundation_audit-rules&pullRequest=170&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=carrot-foundation_audit-rules&pullRequest=170&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=carrot-foundation_audit-rules&pullRequest=170&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=carrot-foundation_audit-rules&pullRequest=170&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=carrot-foundation_audit-rules&pullRequest=170)


author_association: NONE