Update after-trial-ends-notification.ts#1903
Conversation
WalkthroughIntroduces CONSOLE_WEB_PAYMENT_LINK env across environments, adds DEPLOY_WEB_BASE_URL for staging/production, updates STRIPE_CHECKOUT_REDIRECT_URL to derive from it, propagates paymentLink into notifications after trial ends, switches handler to use billingConfig, updates tests accordingly, and adds a typed mockConfig helper for config services. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Svc as TrialStartedHandler
participant Cfg as BillingConfigService
participant Q as JobQueueManager
participant NH as NotificationHandler
participant T as afterTrialEndsNotification
rect rgba(220,235,255,0.5)
note over Svc,Cfg: On trial start
Svc->>Cfg: get(TRIAL_ALLOWANCE_EXPIRATION_DAYS)
Svc->>Cfg: get(TRIAL_DEPLOYMENT_CLEANUP_HOURS)
Svc->>Cfg: get(CONSOLE_WEB_PAYMENT_LINK)
end
Svc->>Q: enqueue afterTrialEnds { userId, vars: { paymentLink } }
rect rgba(230,255,230,0.5)
note over NH,T: On job processing
Q-->>NH: afterTrialEnds job { user, vars }
NH->>T: afterTrialEndsNotification(user, vars)
T-->>NH: Notification payload (includes link)
NH-->>Q: mark complete
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1903 +/- ##
==========================================
- Coverage 44.72% 44.30% -0.42%
==========================================
Files 979 969 -10
Lines 27596 27239 -357
Branches 7113 7085 -28
==========================================
- Hits 12341 12068 -273
+ Misses 14064 13981 -83
+ Partials 1191 1190 -1
*This pull request uses carry forward flags. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (12)
apps/api/env/.env.sample (1)
42-42: Alphabetize the new env key to satisfy dotenv-linter.Move CONSOLE_WEB_PAYMENT_LINK before CORS_WEBSITE_URLS (keys should be sorted). No behavior change.
apps/api/env/.env.functional.test (1)
41-41: Place CONSOLE_WEB_PAYMENT_LINK before FEATURE_FLAGS_ENABLE_ALL (lint).Keeps alphabetical order and fixes dotenv-linter warning.
Apply:
-FEATURE_FLAGS_ENABLE_ALL=true -CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +FEATURE_FLAGS_ENABLE_ALL=trueapps/api/env/.env.local.sample (1)
39-39: Order env keys alphabetically and end file with a newline.Move CONSOLE_WEB_PAYMENT_LINK above NOTIFICATIONS_API_BASE_URL and add trailing newline.
Apply:
-NOTIFICATIONS_API_BASE_URL=http://localhost:3090 -CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +NOTIFICATIONS_API_BASE_URL=http://localhost:3090 +apps/api/env/.env.unit.test (1)
31-31: Fix ordering and trailing newline (dotenv-linter).Put CONSOLE_WEB_PAYMENT_LINK before FEATURE_FLAGS_ENABLE_ALL and add a blank line at EOF.
Apply:
-FEATURE_FLAGS_ENABLE_ALL=true -CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +FEATURE_FLAGS_ENABLE_ALL=true +apps/api/env/.env.production (1)
15-15: Add trailing newline (lint).Apply:
-STRIPE_CHECKOUT_REDIRECT_URL=${DEPLOY_WEB_BASE_URL} +STRIPE_CHECKOUT_REDIRECT_URL=${DEPLOY_WEB_BASE_URL} +apps/api/env/.env.staging (1)
9-11: Minor: place DEPLOY_WEB_BASE_URL before DRIZZLE_MIGRATIONS_FOLDER (lint).Move the DEPLOY_WEB_BASE_URL (and its derived vars) above Line 2 to satisfy dotenv-linter ordering. No behavior change.
apps/api/src/billing/config/env.config.ts (1)
25-27: Validate URLs at the schema boundary.Use url() so misconfigured values fail fast.
Apply:
- STRIPE_ENABLE_COUPONS: z.enum(["true", "false"]).default("false"), - CONSOLE_WEB_PAYMENT_LINK: z.string() + STRIPE_ENABLE_COUPONS: z.enum(["true", "false"]).default("false"), + CONSOLE_WEB_PAYMENT_LINK: z.string().url()Optional (outside selection): also tighten STRIPE_CHECKOUT_REDIRECT_URL to z.string().url() for consistency.
apps/api/src/billing/services/stripe/stripe.service.spec.ts (2)
609-611: Remove “as any” casts in tests to comply with TS guidelines.Replace with precise Stripe types or unions (e.g., null as number | null) and type returned mocks.
Apply examples:
- percent_off: null as any, + percent_off: null as number | null, -jest.spyOn(service, "findPromotionCodeByCode").mockResolvedValue(mockPromotionCode as any); +jest.spyOn(service, "findPromotionCodeByCode").mockResolvedValue(stub(mockPromotionCode)); -jest.spyOn(service, "listCoupons").mockResolvedValue({ coupons: [mockCoupon] } as any); +jest.spyOn(service, "listCoupons").mockResolvedValue(stub({ data: [mockCoupon] }))If needed, import Stripe types and annotate variables explicitly instead of casting.
Also applies to: 645-647, 665-666, 681-683, 699-700
1030-1087: Move setup() inside the root describe and keep it at the bottom.Guideline: setup function must be at the bottom of the root describe block. Define it inside describe(StripeService.name, …) to satisfy structure without changing call sites (function declarations are hoisted).
apps/api/src/app/services/trial-started/trial-started.handler.ts (1)
36-38: Avoid non-null assertion on createdAt.Add a guard to prevent runtime errors if createdAt is unexpectedly missing.
Apply this diff:
- const TRIAL_ALLOWANCE_EXPIRATION_DAYS = this.billingConfig.get("TRIAL_ALLOWANCE_EXPIRATION_DAYS"); - const trialEndsAt = addDays(user.createdAt!, TRIAL_ALLOWANCE_EXPIRATION_DAYS); + const TRIAL_ALLOWANCE_EXPIRATION_DAYS = this.billingConfig.get("TRIAL_ALLOWANCE_EXPIRATION_DAYS"); + if (!user.createdAt) { + this.logger.warn({ event: "TRIAL_STARTED_USER_CREATED_AT_MISSING", userId: user.id }); + return; + } + const trialEndsAt = addDays(user.createdAt, TRIAL_ALLOWANCE_EXPIRATION_DAYS);apps/api/src/app/services/trial-started/trial-started.handler.spec.ts (2)
71-87: Assert deploymentLifetimeInHours is propagated.Also mock TRIAL_DEPLOYMENT_CLEANUP_HOURS to a known value and assert it appears in the description.
Apply this diff:
expect(notificationService.createNotification).toHaveBeenCalledWith({ notificationId: `startTrial.${user.id}`, payload: { summary: expect.stringMatching(/free trial/i), - description: expect.stringMatching(/trial with Akash Network has started/i) + description: expect.stringMatching(/limited to 24 hours/i) }, user: { id: user.id, email: user.email } });And in setup, provide the config key:
- coreConfig: mockConfig<BillingConfigService>({ + coreConfig: mockConfig<BillingConfigService>({ TRIAL_ALLOWANCE_EXPIRATION_DAYS: input?.trialExpirationDays ?? 30, + TRIAL_DEPLOYMENT_CLEANUP_HOURS: 24, CONSOLE_WEB_PAYMENT_LINK: paymentLink })
206-227: Rename test mock to billingConfig for clarity.The handler now injects billingConfig; align the mock name.
Apply this diff:
- const paymentLink = "https://console.akash.network/payment"; + const paymentLink = "https://console.akash.network/payment"; const mocks = { @@ - coreConfig: mockConfig<BillingConfigService>({ + billingConfig: mockConfig<BillingConfigService>({ TRIAL_ALLOWANCE_EXPIRATION_DAYS: input?.trialExpirationDays ?? 30, TRIAL_DEPLOYMENT_CLEANUP_HOURS: 24, CONSOLE_WEB_PAYMENT_LINK: paymentLink }) }; - const handler = new TrialStartedHandler(mocks.notificationService, mocks.jobQueueManager, mocks.userRepository, mocks.logger, mocks.coreConfig); + const handler = new TrialStartedHandler( + mocks.notificationService, + mocks.jobQueueManager, + mocks.userRepository, + mocks.logger, + mocks.billingConfig + ); - return { handler, ...mocks, paymentLink }; + return { handler, ...mocks, paymentLink };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
apps/api/env/.env.functional.test(1 hunks)apps/api/env/.env.local.sample(1 hunks)apps/api/env/.env.production(1 hunks)apps/api/env/.env.sample(1 hunks)apps/api/env/.env.staging(1 hunks)apps/api/env/.env.unit.test(1 hunks)apps/api/src/app/services/trial-started/trial-started.handler.spec.ts(5 hunks)apps/api/src/app/services/trial-started/trial-started.handler.ts(3 hunks)apps/api/src/billing/config/env.config.ts(1 hunks)apps/api/src/billing/services/stripe/stripe.service.spec.ts(1 hunks)apps/api/src/notifications/services/notification-handler/notification.handler.spec.ts(1 hunks)apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts(1 hunks)apps/api/test/services/mock-config.service.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.spec.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/no-jest-mock.mdc)
Don't use
jest.mock()to mock dependencies in test files. Instead, usejest-mock-extendedto create mocks and pass mocks as dependencies to the service under test.
**/*.spec.{ts,tsx}: Usesetupfunction instead ofbeforeEachin test files
setupfunction must be at the bottom of the rootdescribeblock in test files
setupfunction creates an object under test and returns it
setupfunction should accept a single parameter with inline type definition
Don't use shared state insetupfunction
Don't specify return type ofsetupfunction
Files:
apps/api/src/billing/services/stripe/stripe.service.spec.tsapps/api/src/app/services/trial-started/trial-started.handler.spec.tsapps/api/src/notifications/services/notification-handler/notification.handler.spec.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/api/src/billing/services/stripe/stripe.service.spec.tsapps/api/src/notifications/services/notification-templates/after-trial-ends-notification.tsapps/api/src/billing/config/env.config.tsapps/api/test/services/mock-config.service.tsapps/api/src/app/services/trial-started/trial-started.handler.spec.tsapps/api/src/app/services/trial-started/trial-started.handler.tsapps/api/src/notifications/services/notification-handler/notification.handler.spec.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/api/src/billing/services/stripe/stripe.service.spec.tsapps/api/src/notifications/services/notification-templates/after-trial-ends-notification.tsapps/api/src/billing/config/env.config.tsapps/api/test/services/mock-config.service.tsapps/api/src/app/services/trial-started/trial-started.handler.spec.tsapps/api/src/app/services/trial-started/trial-started.handler.tsapps/api/src/notifications/services/notification-handler/notification.handler.spec.ts
🧠 Learnings (2)
📚 Learning: 2025-06-10T14:19:14.122Z
Learnt from: ygrishajev
PR: akash-network/console#1461
File: apps/notifications/src/modules/alert/services/deployment-alert/deployment-alert.service.ts:194-197
Timestamp: 2025-06-10T14:19:14.122Z
Learning: The alert.CONSOLE_WEB_URL environment variable in the notifications app is controlled and configured by the Akash team, reducing XSS concerns for HTML link generation in alert messages.
Applied to files:
apps/api/env/.env.local.sample
📚 Learning: 2025-07-21T08:24:24.269Z
Learnt from: CR
PR: akash-network/console#0
File: .cursor/rules/no-jest-mock.mdc:0-0
Timestamp: 2025-07-21T08:24:24.269Z
Learning: Applies to **/*.spec.{ts,tsx} : Don't use `jest.mock()` to mock dependencies in test files. Instead, use `jest-mock-extended` to create mocks and pass mocks as dependencies to the service under test.
Applied to files:
apps/api/test/services/mock-config.service.ts
🧬 Code graph analysis (5)
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts (1)
apps/api/src/notifications/services/notification/notification.service.ts (1)
CreateNotificationInput(74-76)
apps/api/test/services/mock-config.service.ts (1)
apps/api/src/core/services/config/config.service.ts (1)
ConfigService(9-22)
apps/api/src/app/services/trial-started/trial-started.handler.spec.ts (1)
apps/api/test/services/mock-config.service.ts (1)
mockConfig(10-14)
apps/api/src/app/services/trial-started/trial-started.handler.ts (1)
apps/api/src/notifications/services/notification-templates/start-trial-notification.ts (1)
startTrialNotification(4-28)
apps/api/src/notifications/services/notification-handler/notification.handler.spec.ts (1)
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts (1)
afterTrialEndsNotification(4-16)
🪛 dotenv-linter (3.3.0)
apps/api/env/.env.unit.test
[warning] 31-31: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
[warning] 31-31: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the FEATURE_FLAGS_ENABLE_ALL key
(UnorderedKey)
apps/api/env/.env.staging
[warning] 9-9: [UnorderedKey] The DEPLOY_WEB_BASE_URL key should go before the DRIZZLE_MIGRATIONS_FOLDER key
(UnorderedKey)
apps/api/env/.env.sample
[warning] 42-42: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the CORS_WEBSITE_URLS key
(UnorderedKey)
apps/api/env/.env.local.sample
[warning] 39-39: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
[warning] 39-39: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the NOTIFICATIONS_API_BASE_URL key
(UnorderedKey)
apps/api/env/.env.production
[warning] 15-15: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
apps/api/env/.env.functional.test
[warning] 41-41: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the FEATURE_FLAGS_ENABLE_ALL key
(UnorderedKey)
🔇 Additional comments (8)
apps/api/env/.env.production (1)
13-15: Good: derive payment link and checkout redirect from a single base.Nice consolidation via DEPLOY_WEB_BASE_URL.
apps/api/src/billing/services/stripe/stripe.service.spec.ts (1)
562-565: LGTM: card details nested under card aligns with generator shape.Matches updated test data structures used elsewhere in the suite.
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts (2)
4-10: Signature + template update LGTM.Accepting vars and embedding the payment link aligns with the new scheduling flow.
9-9: Validate/sanitize paymentLink before embedding in HTML.If the renderer treats description as HTML, guard against javascript: or malformed URLs (e.g., ensure http/https or sanitize downstream).
apps/api/src/notifications/services/notification-handler/notification.handler.spec.ts (1)
194-207: After-trial vars propagation test is correct.The test now verifies paymentLink flows into the template as intended.
apps/api/src/app/services/trial-started/trial-started.handler.ts (3)
18-24: DI switch to BillingConfigService looks good.Constructor and usage align with config moves.
61-75: Negative/odd singletonKey suffixes when trial < 7 days.If TRIAL_ALLOWANCE_EXPIRATION_DAYS < 7, suffix becomes negative. Confirm config guarantees or handle min bound.
92-95: Prefer template-specific typed vars over Record<string, any>.Define NotificationJob as a discriminated union so vars are type-safe per template.
Example (in notification.handler.ts):
+type NotificationTemplate = "startTrial" | "beforeTrialEnds" | "trialEnded" | "afterTrialEnds"; +type NotificationVars = { + startTrial: { trialEndsAt: string; deploymentLifetimeInHours: number }; + beforeTrialEnds: { trialEndsAt: string }; + trialEnded: undefined; + afterTrialEnds: { paymentLink: string }; +}; -export type NotificationJob = { template: string; userId: string; vars?: Record<string, any>; conditions?: Record<string, unknown>; version: number }; +export type NotificationJob<T extends NotificationTemplate = NotificationTemplate> = { + template: T; + userId: string; + vars?: NotificationVars[T]; + conditions?: Record<string, unknown>; + version: number; +};Search for and update call sites that rely on vars?: Record<string, any> to avoid breaking changes.
Signed-off-by: Anil Murty <19495789+anilmurty@users.noreply.github.com>
ac70950 to
0af403a
Compare
0af403a to
c2b231f
Compare
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (7)
apps/api/env/.env.sample (1)
42-42: Reorder the new key to satisfy dotenv-linter (and keep files consistent).Move
CONSOLE_WEB_PAYMENT_LINKbeforeCORS_WEBSITE_URLS. Consider adding an example value to clarify format.-UNLEASH_SERVER_API_URL= -CONSOLE_WEB_PAYMENT_LINK= +UNLEASH_SERVER_API_URL= + +# Configuration +CONSOLE_WEB_PAYMENT_LINK= CORS_WEBSITE_URLS=apps/api/env/.env.functional.test (1)
41-41: Key order: place CONSOLE_WEB_PAYMENT_LINK before FEATURE_FLAGS_ENABLE_ALL.Fixes dotenv-linter UnorderedKey warning.
-FEATURE_FLAGS_ENABLE_ALL=true -CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +FEATURE_FLAGS_ENABLE_ALL=trueapps/api/env/.env.local.sample (1)
39-39: Swap order and add trailing newline.Put
CONSOLE_WEB_PAYMENT_LINKbeforeNOTIFICATIONS_API_BASE_URLand ensure EOF newline.-NOTIFICATIONS_API_BASE_URL=http://localhost:3090 -CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +NOTIFICATIONS_API_BASE_URL=http://localhost:3090 +apps/api/env/.env.unit.test (1)
31-31: Key order and EOF newline.Place
CONSOLE_WEB_PAYMENT_LINKbeforeFEATURE_FLAGS_ENABLE_ALLand add a trailing newline.-FEATURE_FLAGS_ENABLE_ALL=true -CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +CONSOLE_WEB_PAYMENT_LINK=http://localhost:3000/payment +FEATURE_FLAGS_ENABLE_ALL=true +apps/api/env/.env.production (1)
13-15: Add trailing newline (dotenv-linter).No functional change; just formatting to satisfy the linter.
DEPLOY_WEB_BASE_URL=https://console.akash.network CONSOLE_WEB_PAYMENT_LINK=${DEPLOY_WEB_BASE_URL}/payment STRIPE_CHECKOUT_REDIRECT_URL=${DEPLOY_WEB_BASE_URL} +apps/api/env/.env.staging (1)
9-11: Reorder DEPLOY_WEB_BASE_URL before DRIZZLE_MIGRATIONS_FOLDER.Matches dotenv-linter’s ordering rule and keeps prod/staging consistent.
-SERVER_ORIGIN=https://console-api-sandbox.akash.network -DRIZZLE_MIGRATIONS_FOLDER=./dist/drizzle +DEPLOY_WEB_BASE_URL=https://console-beta.akash.network +SERVER_ORIGIN=https://console-api-sandbox.akash.network +DRIZZLE_MIGRATIONS_FOLDER=./dist/drizzle AUTH0_JWKS_URI=https://dev-5aprb0lr.us.auth0.com/.well-known/jwks.json AUTH0_AUDIENCE=https://console-api.akash.network AUTH0_ISSUER=https://dev-5aprb0lr.us.auth0.com/ AUTH0_M2M_DOMAIN=dev-5aprb0lr.us.auth0.com BILLING_ENABLED=true AMPLITUDE_SAMPLING=1 -DEPLOY_WEB_BASE_URL=https://console-beta.akash.network CONSOLE_WEB_PAYMENT_LINK=${DEPLOY_WEB_BASE_URL}/payment STRIPE_CHECKOUT_REDIRECT_URL=${DEPLOY_WEB_BASE_URL}apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts (1)
4-4: Type looks good; consider a named type for reuse.Minor: define a reusable type for
varsto keep templates consistent.-export function afterTrialEndsNotification(user: UserOutput, vars: { paymentLink: string }): CreateNotificationInput { +type AfterTrialEndsVars = Readonly<{ paymentLink: string }>; +export function afterTrialEndsNotification(user: UserOutput, vars: AfterTrialEndsVars): CreateNotificationInput {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
apps/api/env/.env.functional.test(1 hunks)apps/api/env/.env.local.sample(1 hunks)apps/api/env/.env.production(1 hunks)apps/api/env/.env.sample(1 hunks)apps/api/env/.env.staging(1 hunks)apps/api/env/.env.unit.test(1 hunks)apps/api/src/app/services/trial-started/trial-started.handler.spec.ts(5 hunks)apps/api/src/app/services/trial-started/trial-started.handler.ts(3 hunks)apps/api/src/billing/config/env.config.ts(1 hunks)apps/api/src/notifications/services/notification-handler/notification.handler.spec.ts(1 hunks)apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts(1 hunks)apps/api/test/services/mock-config.service.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- apps/api/src/billing/config/env.config.ts
- apps/api/test/services/mock-config.service.ts
- apps/api/src/app/services/trial-started/trial-started.handler.spec.ts
- apps/api/src/app/services/trial-started/trial-started.handler.ts
- apps/api/src/notifications/services/notification-handler/notification.handler.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
Never use type any or cast to type any. Always define the proper TypeScript types.
Files:
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/general.mdc)
**/*.{js,ts,tsx}: Never use deprecated methods from libraries.
Don't add unnecessary comments to the code
Files:
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts
🧠 Learnings (1)
📚 Learning: 2025-06-10T14:19:14.122Z
Learnt from: ygrishajev
PR: akash-network/console#1461
File: apps/notifications/src/modules/alert/services/deployment-alert/deployment-alert.service.ts:194-197
Timestamp: 2025-06-10T14:19:14.122Z
Learning: The alert.CONSOLE_WEB_URL environment variable in the notifications app is controlled and configured by the Akash team, reducing XSS concerns for HTML link generation in alert messages.
Applied to files:
apps/api/env/.env.local.sample
🧬 Code graph analysis (1)
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts (1)
apps/api/src/notifications/services/notification/notification.service.ts (1)
CreateNotificationInput(74-76)
🪛 dotenv-linter (3.3.0)
apps/api/env/.env.functional.test
[warning] 41-41: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the FEATURE_FLAGS_ENABLE_ALL key
(UnorderedKey)
apps/api/env/.env.local.sample
[warning] 39-39: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
[warning] 39-39: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the NOTIFICATIONS_API_BASE_URL key
(UnorderedKey)
apps/api/env/.env.production
[warning] 15-15: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
apps/api/env/.env.sample
[warning] 42-42: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the CORS_WEBSITE_URLS key
(UnorderedKey)
apps/api/env/.env.staging
[warning] 9-9: [UnorderedKey] The DEPLOY_WEB_BASE_URL key should go before the DRIZZLE_MIGRATIONS_FOLDER key
(UnorderedKey)
apps/api/env/.env.unit.test
[warning] 31-31: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
[warning] 31-31: [UnorderedKey] The CONSOLE_WEB_PAYMENT_LINK key should go before the FEATURE_FLAGS_ENABLE_ALL key
(UnorderedKey)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: validate / validate-app
- GitHub Check: test-build
🔇 Additional comments (1)
apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts (1)
8-10: Validate/sanitize paymentLink and confirm HTML rendering path
- Found one embedded anchor: apps/api/src/notifications/services/notification-templates/after-trial-ends-notification.ts:9.
- Add URL validation for the env value (example): CONSOLE_WEB_PAYMENT_LINK: z.string().url() — (e.g., apps/api/src/billing/config/env.config.ts).
- Confirm the notification consumer renders
descriptionas sanitized HTML; if it does not, remove embedded HTML and deliver the link as plain text/markdown or sanitize/escape the URL before rendering.
Summary by CodeRabbit
New Features
Bug Fixes