Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New pricing #308

Merged
merged 22 commits into from
Jun 30, 2024
Merged

New pricing #308

merged 22 commits into from
Jun 30, 2024

Conversation

loicknuchel
Copy link
Contributor

@loicknuchel loicknuchel commented Jun 19, 2024

Summary by CodeRabbit

  • New Features

    • Introduced support for multiple email contacts and Stripe pricing plans.
    • Added new subscription plans: Free, Solo, Team, and Enterprise.
    • Implemented features for plan validation and free trial management.
  • Bug Fixes

    • Fixed email configuration fallbacks to ensure correct email usage.
  • Refactor

    • Streamlined logic for Stripe subscription handling and email configurations.
    • Updated plan detail handling in the organization module, improving plan management and validation processes.
  • Style

    • Updated streak reward descriptions to reflect new achievements and features.
  • Documentation

    • Updated INSTALL.md to reflect new email and Stripe configurations.
    • Removed outdated free plan parameters in configuration files.
  • Chores

    • Preloaded additional resources in organization queries for better plan validation.

Copy link

coderabbitai bot commented Jun 19, 2024

Walkthrough

This update includes a significant overhaul of the configuration and subscription management system, focusing on new email and Stripe configuration parameters, refined organization and plan management functions, and updated constraints for various plans. Additionally, it introduces UI changes to subscription-related templates to reflect these backend modifications and enhance overall user experience.

Changes

File(s) Change Summary
.env.example, INSTALL.md Updated environment variables and renamed support email configurations. Added new Stripe plan configurations.
tailwind.config.js Expanded the safelist with new classes for responsive design support.
config/config.exs, config/runtime.exs Updated versioning and added configuration parameters for email and pricing plans. Refined email fallback logic and new pricing configurations.
backend/lib/azimutt.ex Overhauled plans function with updated attributes, added new plans, and updated the limits function.
backend/lib/azimutt/admin.ex Renamed and refactored count_stripe_subscriptions to count_paid_organizations with updated logic.
backend/lib/azimutt/clever_cloud.ex, backend/lib/azimutt/heroku.ex Removed allowed_members function; integrated logic directly into add_member_if_needed.
backend/lib/azimutt/organizations.ex, organization.ex, organization_plan.ex Added new fields and functions for handling plan validation and subscriptions. Refined organization and plan handling logic.
backend/lib/azimutt/projects.ex Updated filtering logic for project sharing permissions.
backend/lib/azimutt/services/cockpit_srv.ex, backend/lib/stripe_srv.ex Added new parameters in API calls and pricing functions. Updated subscription and session handling functions.
templates/partials/_streak.html.heex Refined rewards and descriptions for different streak milestones.
templates/organization/billing.html.heex, templates/organization/subscribe.html.heex Redesigned layout and content for different subscription plans and legacy plan handling.

Sequence Diagram(s)

Poem

In the code's vast land, a change does whisk,
Emails now support with an extra brisk.
Plans evolve, subscriptions bloom,
Stripe's with us, no more a gloom!
A rabbit's joy, for code so tight,
Azimutt shines with updated might.

🐇✨


Tip

Early access features: enabled

We are currently testing the following features in early access:

  • OpenAI gpt-4o model for code reviews and chat: OpenAI claims that this model is better at understanding and generating code than the previous models. We seek your feedback over the next few weeks before making it generally available.

Note:

  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.
  • Please join our Discord Community to provide feedback and report issues.
  • OSS projects are always opted into early access features.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • 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 generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @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 as 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.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@loicknuchel loicknuchel marked this pull request as ready for review June 26, 2024 16:45
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Outside diff range and nitpick comments (2)
backend/lib/azimutt_web/controllers/organization_invitation_controller.ex (2)

Line range hint 10-10: Consider addressing the FIXME comment.

The method get_organization_plan is marked for removal. Ensure that its logic is refactored into the new plan management approach before removing this method.

Would you like assistance in refactoring this method?


Line range hint 42-42: Consider enhancing error handling in the refusal process.

Similar to the accept method, provide more detailed error messages or logs to help diagnose issues when an invitation is refused.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9929ba9 and 1e4a806.

Files selected for processing (52)
  • .env.example (2 hunks)
  • INSTALL.md (2 hunks)
  • backend/assets/tailwind.config.js (1 hunks)
  • backend/config/config.exs (1 hunks)
  • backend/config/runtime.exs (2 hunks)
  • backend/lib/azimutt.ex (1 hunks)
  • backend/lib/azimutt/admin.ex (1 hunks)
  • backend/lib/azimutt/clever_cloud.ex (2 hunks)
  • backend/lib/azimutt/heroku.ex (2 hunks)
  • backend/lib/azimutt/organizations.ex (6 hunks)
  • backend/lib/azimutt/organizations/organization.ex (4 hunks)
  • backend/lib/azimutt/organizations/organization_plan.ex (1 hunks)
  • backend/lib/azimutt/services/cockpit_srv.ex (6 hunks)
  • backend/lib/azimutt/services/stripe_srv.ex (4 hunks)
  • backend/lib/azimutt/stripe_handler.ex (2 hunks)
  • backend/lib/azimutt/tracking.ex (6 hunks)
  • backend/lib/azimutt_web/admin/dashboard/dashboard_controller.ex (1 hunks)
  • backend/lib/azimutt_web/admin/dashboard/index.html.heex (1 hunks)
  • backend/lib/azimutt_web/admin/organization/_organizations_table.html.heex (1 hunks)
  • backend/lib/azimutt_web/admin/organization/organization_view.ex (1 hunks)
  • backend/lib/azimutt_web/admin/organization/show.html.heex (2 hunks)
  • backend/lib/azimutt_web/components/icon.ex (4 hunks)
  • backend/lib/azimutt_web/controllers/clever_cloud_controller.ex (1 hunks)
  • backend/lib/azimutt_web/controllers/heroku_controller.ex (1 hunks)
  • backend/lib/azimutt_web/controllers/organization_billing_controller.ex (2 hunks)
  • backend/lib/azimutt_web/controllers/organization_controller.ex (1 hunks)
  • backend/lib/azimutt_web/controllers/organization_invitation_controller.ex (2 hunks)
  • backend/lib/azimutt_web/controllers/organization_member_controller.ex (3 hunks)
  • backend/lib/azimutt_web/controllers/subscribe_controller.ex (1 hunks)
  • backend/lib/azimutt_web/controllers/user_onboarding_controller.ex (3 hunks)
  • backend/lib/azimutt_web/router.ex (3 hunks)
  • backend/lib/azimutt_web/services/billing_srv.ex (2 hunks)
  • backend/lib/azimutt_web/templates/blog/_blog_footer.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/layout/_organization_left_bar.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/_subscription_show.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/billing.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/new.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/show.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/subscribe.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization_member/index.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/partials/_pricing_features_desktop.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/partials/_pricing_features_label.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/partials/_pricing_features_mobile.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/partials/_pricing_features_value.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/partials/_pricing_plan_dark.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/partials/_pricing_plan_light.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/subscribe/index.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/user_onboarding/about_your_company.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/user_onboarding/explore_or_design.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/user_onboarding/keep_in_touch.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/user_onboarding/welcome.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/website/_footer.html.heex (1 hunks)
Files not processed due to max files limit (15)
  • backend/lib/azimutt_web/templates/website/feature-support.html.heex
  • backend/lib/azimutt_web/templates/website/index.html.heex
  • backend/lib/azimutt_web/templates/website/pricing.html.heex
  • backend/lib/azimutt_web/views/api/health_view.ex
  • backend/lib/azimutt_web/views/layout_view.ex
  • backend/lib/azimutt_web/views/organization_member_view.ex
  • backend/lib/azimutt_web/views/organization_view.ex
  • backend/lib/azimutt_web/views/subscribe_view.ex
  • backend/priv/repo/migrations/20240624135054_manage_plans_in_db.exs
  • backend/test/azimutt/organizations_test.exs
  • backend/test/azimutt/services/stripe_srv_test.exs
  • backend/test/azimutt_web/controllers/organization_controller_test.exs
  • frontend/src/Components/Slices/ProjectSaveDialogBody.elm
  • frontend/src/Conf.elm
  • frontend/src/Models/Plan.elm
Files not reviewed due to errors (5)
  • backend/lib/azimutt_web/templates/partials/_pricing_plan_light.html.heex (no review received)
  • backend/lib/azimutt/services/stripe_srv.ex (no review received)
  • backend/lib/azimutt_web/controllers/organization_member_controller.ex (no review received)
  • backend/lib/azimutt/organizations/organization.ex (no review received)
  • backend/lib/azimutt_web/controllers/heroku_controller.ex (no review received)
Files skipped from review due to trivial changes (12)
  • backend/assets/tailwind.config.js
  • backend/lib/azimutt_web/admin/dashboard/index.html.heex
  • backend/lib/azimutt_web/controllers/user_onboarding_controller.ex
  • backend/lib/azimutt_web/templates/organization/_subscription_show.html.heex
  • backend/lib/azimutt_web/templates/organization/show.html.heex
  • backend/lib/azimutt_web/templates/partials/_pricing_features_label.html.heex
  • backend/lib/azimutt_web/templates/partials/_pricing_features_mobile.html.heex
  • backend/lib/azimutt_web/templates/partials/_pricing_plan_dark.html.heex
  • backend/lib/azimutt_web/templates/subscribe/index.html.heex
  • backend/lib/azimutt_web/templates/user_onboarding/explore_or_design.html.heex
  • backend/lib/azimutt_web/templates/user_onboarding/keep_in_touch.html.heex
  • backend/lib/azimutt_web/templates/user_onboarding/welcome.html.heex
Additional context used
LanguageTool
INSTALL.md

[uncategorized] ~9-~9: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL)
Context: ...age](#build-your-own-docker-image) - Bare metal installation...


[uncategorized] ~27-~27: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL)
Context: ...image](#build-your-own-docker-image) - Bare metal installation...


[typographical] ~49-~49: Consider adding a comma here. (FOR_THAT_COMMA)
Context: ...and give them to your Docker container. For that you can use the --env-file option wit...


[grammar] ~49-~49: Two determiners in a row. Choose either “a” or “the”. (DT_DT)
Context: ...ou can use the --env-file option with a the .env.example file set up with your co...


[uncategorized] ~78-~78: Possible missing preposition found. (AI_HYDRA_LEO_MISSING_TO)
Context: ...# Step 2: Set up environment variables Define your [environment variables](#environme...


[uncategorized] ~110-~110: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL)
Context: ...nning on http://localhost:4000. ### Bare metal installation TODO But in short you wi...


[uncategorized] ~131-~131: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short). (COMMA_COMPOUND_SENTENCE)
Context: ...and others), should be at least 64 bytes and you probably want a random value for it...


[uncategorized] ~160-~160: If this is a compound adjective that modifies the following noun, use a hyphen. (EN_COMPOUND_ADJECTIVE_INTERNAL)
Context: ...imutt.app`): email shown in Azimutt for high priority support ### Key features At least on...


[typographical] ~160-~160: Except for inverted sentences, ‘will us’ requires a question mark at the end of the sentence. (MD_PRP_QUESTION_MARK)
Context: ...mail shown in Azimutt for high priority support ### Key features At least one of aut...


[typographical] ~178-~178: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence. (THUS_SENTENCE)
Context: ...to use Azimutt until they confirm their email, otherwise they will have a soft confirmation bann...


[grammar] ~182-~182: Did you mean “working”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun. (ALLOW_TO)
Context: ...he global organization is shown (allows to work like a mono-tenant app) - RECAPTCHA (...


[grammar] ~190-~190: Did you mean “using”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun. (ALLOW_TO)
Context: ... TWITTER (optional): if true, allow to use Twitter API to fetch tweets & unlock fe...


[typographical] ~199-~199: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence. (THUS_SENTENCE)
Context: ...ional): if true, will show the public site, otherwise home will redirect to login page (you p...


[style] ~199-~199: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing. (REP_PROBABLY)
Context: ...e home will redirect to login page (you probably don't want it) - GITHUB (optional): i...


[grammar] ~200-~200: Did you mean “using”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun. (ALLOW_TO)
Context: ...- GITHUB (optional): if true, allow to use GitHub API, no real usage for now -...


[grammar] ~209-~209: Did you mean “purchasing”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun. (ALLOW_TO)
Context: ...- STRIPE (optional): if true, allow to purchase plans with Stripe...

Markdownlint
INSTALL.md

134-134: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


135-135: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


136-136: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


138-138: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


139-139: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


140-140: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


141-141: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


142-142: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


143-143: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


144-144: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


146-146: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


147-147: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


148-148: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


149-149: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


150-150: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


151-151: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


152-152: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


153-153: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


154-154: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


155-155: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


156-156: Expected: 4; Actual: 8 (MD007, ul-indent)
Unordered list indentation


169-169: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


170-170: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


182-182: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


184-184: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


185-185: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


186-186: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


188-188: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


189-189: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


191-191: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


192-192: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


193-193: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


194-194: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


201-201: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


203-203: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


204-204: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


206-206: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


207-207: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


208-208: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


210-210: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


211-211: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


212-212: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


213-213: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


214-214: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


215-215: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


216-216: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


217-217: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


219-219: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


220-220: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


221-221: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


223-223: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


224-224: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


225-225: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


227-227: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


12-12: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


22-22: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


29-29: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


36-36: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


45-45: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


60-60: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


67-67: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


76-76: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


87-87: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


94-94: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


109-109: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


117-117: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


122-122: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


162-162: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


172-172: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


196-196: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


132-132: null (MD034, no-bare-urls)
Bare URL used

Gitleaks
INSTALL.md

210-210: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data. (stripe-access-token)

Additional comments not posted (50)
backend/lib/azimutt_web/controllers/subscribe_controller.ex (1)

7-17: Ensure robust error handling in subscription index action.

The index action uses a with clause to handle plan and price fetching. Ensure that there is an else block to handle cases where plan or price fetching fails, to avoid rendering errors or unexpected behavior.

backend/lib/azimutt/clever_cloud.ex (1)

56-66: Review the updated member addition logic.

The logic to add a member only if the number of existing members is less than plan_seats is a good control. However, ensure that this logic aligns with business requirements, especially in edge cases where plan_seats might change dynamically.

backend/lib/azimutt_web/templates/organization/subscribe.html.heex (1)

24-26: Validate the rendering of pricing plans.

Ensure that the render calls for pricing plans are correctly pulling data from Azimutt.plans and that the conditional rendering based on free_trial_used is functioning as intended.

Verification successful

Validate the rendering of pricing plans.

The render calls for pricing plans correctly pull data from Azimutt.plans, and the conditional rendering based on free_trial_used functions as intended.

  • The @organization.free_trial_used variable correctly switches between "Subscribe" and "Start free trial".
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correct rendering of pricing plans based on `free_trial_used`.

# Test: Check if the conditional rendering switches correctly between "Subscribe" and "Start free trial".
echo "Checking rendering logic..."
# This is a placeholder; implement the actual logic to verify.

Length of output: 64



Script:

#!/bin/bash
# Description: Verify the correct rendering of pricing plans based on `free_trial_used`.

# Locate the template file and extract the relevant lines for rendering the pricing plans.
echo "Extracting rendering logic from subscribe.html.heex..."
rg -A 3 -B 3 '<%= render AzimuttWeb.PartialsView, "_pricing_plan_light.html"' backend/lib/azimutt_web/templates/organization/subscribe.html.heex

# Verify the usage of @organization.free_trial_used in the template file.
echo "Checking usage of @organization.free_trial_used..."
rg '@organization\.free_trial_used' backend/lib/azimutt_web/templates/organization/subscribe.html.heex

Length of output: 2032

backend/lib/azimutt/heroku.ex (1)

67-77: Review and verify the updated member addition logic for Heroku.

The logic to add a member based on plan_seats is consistent with the changes in clever_cloud.ex. Ensure that this logic is tested thoroughly, especially when plan_seats is at its limit.

.env.example (2)

51-53: Addition of new email environment variables approved.

The new variables CONTACT_EMAIL, SUPPORT_EMAIL, and ENTERPRISE_SUPPORT_EMAIL are consistent with the changes outlined in the PR summary and are necessary for the expanded email configuration settings.


126-130: Addition of Stripe pricing environment variables approved.

Ensure these variables are appropriately set in deployment environments as they are crucial for the Stripe payment configurations.

backend/lib/azimutt_web/templates/blog/_blog_footer.html.heex (1)

20-20: Addition of email contact link approved.

The new email link in the blog footer using Azimutt.config(:contact_email) enhances user accessibility and provides a direct contact option, aligning with the new email configurations.

backend/lib/azimutt_web/templates/partials/_pricing_features_desktop.html.heex (1)

1-68: Dynamic rendering of pricing features approved.

The template dynamically renders pricing plans and their features using Elixir's templating language, which is well-suited for such tasks in Phoenix applications. The implementation is clean and maintainable.

backend/config/config.exs (1)

31-32: Version update and addition of version date approved.

Updating the application version to "2.1.0" and adding a version_date are standard practices for managing releases, especially when significant new features or changes are introduced.

backend/lib/azimutt_web/admin/dashboard/dashboard_controller.ex (1)

17-17: Addition of paid organization count metric approved.

The new metric for counting paid organizations in the admin dashboard supports enhanced tracking and reporting of business metrics.

backend/lib/azimutt_web/admin/organization/show.html.heex (1)

7-9: Correct Integration of Stripe Customer Link

The addition of the Stripe customer link and the display of the plan name align well with the backend updates and the new plan management features. Ensure that the link correctly leads to the Stripe customer page and that the plan name displays as intended.

Verification successful

Correct Integration of Stripe Customer Link

The addition of the Stripe customer link and the display of the plan name align well with the backend updates and the new plan management features. The implementation of StripeSrv.customer_url is confirmed in both show.html.heex and _organizations_table.html.heex.

  • backend/lib/azimutt_web/admin/organization/show.html.heex
  • backend/lib/azimutt_web/admin/organization/_organizations_table.html.heex
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correct rendering of the Stripe customer link and plan name.

# Test: Search for the usage of `customer_url` in the template to ensure it's implemented correctly.
rg --type html.heex $'customer_url'

Length of output: 68



Script:

#!/bin/bash
# Description: Verify the correct rendering of the Stripe customer link and plan name.

# Test: Search for the usage of `customer_url` in .heex files to ensure it's implemented correctly.
rg 'customer_url' --glob '*.heex'

Length of output: 464

backend/lib/azimutt_web/controllers/clever_cloud_controller.ex (1)

54-54: Review of Member Addition Logic in Clever Cloud Integration

The logic to add a member to an organization in the Clever Cloud controller has been updated. Ensure that this integration correctly handles all edge cases, such as duplicate member additions and error handling.

Verification successful

Review of Member Addition Logic in Clever Cloud Integration

The function add_member_if_needed is defined and used appropriately in the Clever Cloud controller. The implementation appears consistent with its usage in the Heroku controller. Ensure that the function handles edge cases, such as duplicate member additions and error handling, correctly.

  • backend/lib/azimutt_web/controllers/clever_cloud_controller.ex: Line 54
  • backend/lib/azimutt/clever_cloud.ex: Definition of add_member_if_needed
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correct handling of member addition in the Clever Cloud integration.

# Test: Search for the usage of `add_member_if_needed` in all controllers to ensure it's implemented correctly and consistently.
rg --type ex $'add_member_if_needed'

Length of output: 62



Script:

#!/bin/bash
# Description: Verify the correct handling of member addition in the Clever Cloud integration.

# Test: Search for the usage of `add_member_if_needed` in all controllers to ensure it's implemented correctly and consistently.
rg --type elixir 'add_member_if_needed'

Length of output: 568

backend/lib/azimutt_web/templates/user_onboarding/about_your_company.html.heex (1)

14-14: Review of Input Field for Company Name

The input field for the company name is set with a placeholder and marked as required. Ensure that this field is properly sanitized on the backend to prevent XSS attacks and that it adheres to usability standards.

backend/lib/azimutt/organizations/organization_plan.ex (1)

28-97: Comprehensive Update to Plan Attributes

The updates to the plan attributes in the OrganizationPlan module are extensive and align with the new plan configurations described in the PR summary. Ensure that these changes are correctly reflected in the frontend and other parts of the system where plans are used or displayed.

Verification successful

Comprehensive Update to Plan Attributes

The updates to the plan attributes in the OrganizationPlan module are correctly reflected in various parts of the system, including backend/lib/azimutt/organizations.ex and backend/lib/azimutt_web/admin/organization/organization_controller.ex. This ensures that the new configurations are effectively integrated and used throughout the codebase.

  • backend/lib/azimutt/organizations.ex
  • backend/lib/azimutt_web/admin/organization/organization_controller.ex
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correct usage and reflection of updated plan attributes across the system.

# Test: Search for the usage of `OrganizationPlan` attributes in the system to ensure they are updated and used correctly.
rg --type ex $'OrganizationPlan'

Length of output: 58



Script:

#!/bin/bash
# Description: Verify the correct usage and reflection of updated plan attributes across the system.

# Test: Search for the usage of `OrganizationPlan` attributes in the system to ensure they are updated and used correctly.
rg --type elixir 'OrganizationPlan'

Length of output: 2895

backend/lib/azimutt/stripe_handler.ex (3)

26-32: Validate the organization plan after deleting a subscription.

After handling the customer.subscription.deleted event, the organization's plan is validated. This is a good practice as it ensures the organization's state is consistent with the absence of an active subscription.


66-68: Confirm the organization's existence before opening the billing portal.

The function handling the billing_portal.session.created event properly checks the organization's existence before proceeding. This is crucial to ensure that only valid, existing organizations can access the billing portal.
[APROVED]


94-94: Review and potentially remove commented code.

The commented IO.inspect line could either be removed or replaced with a proper logging statement if needed for debugging.

-    # IO.inspect(event, label: "stripe_unhandled_event")
+    Logger.debug("Unhandled Stripe event: #{inspect(event)}")
backend/lib/azimutt_web/templates/organization/billing.html.heex (3)

3-8: Ensure dynamic email retrieval for enterprise support.

The code properly uses the Azimutt.config(:enterprise_support_email) for displaying the contact email, which aligns with the changes in the .env.example and runtime.exs. This ensures that the email is fetched dynamically, adhering to best practices for configuration management.


9-20: Check dynamic seat management and messages.

The template dynamically adjusts the display based on the number of seats (@organization.plan_seats) and the maximum seats allowed (max_seats). This is a good use of dynamic content based on the organization's current plan. However, the text on line 19 has a minor grammatical error.

- Change you seats using the "Manage your subscription" button.
+ Change your seats using the "Manage your subscription" button.

22-37: Review legacy plan warning and migration advice.

This segment effectively informs users of a legacy plan and provides guidance on how to migrate. It uses conditional rendering based on the plan type and includes a link to the pricing page, which is good for user navigation. Ensure that the migration steps are clear and the external links are secure.

backend/lib/azimutt_web/controllers/organization_billing_controller.ex (4)

32-33: Check conditional logic for Stripe subscription view.

The conditional check for organization.stripe_customer_id and StripeSrv.stripe_configured?() is crucial for determining if the Stripe-related view should be rendered. This is a good practice to ensure that the functionality is available before attempting to use it.


39-51: Review handling of various subscription statuses.

The handling of different subscription statuses using a cond block is a robust way to manage the flow based on the subscription state. Each condition correctly redirects to appropriate views and messages. This segment effectively manages user expectations and provides clear communication based on the subscription status.


60-68: Ensure plan validation and refresh functionality.

The refresh function validates the organization's plan and provides feedback to the user. This is a crucial feature for maintaining accurate user data and enhancing user experience by allowing manual refreshes of plan information.


131-131: Improve user guidance on subscription cancellation.

The message provided during cancellation offers a contact option, which is good for user support. However, consider adding more detailed guidance or a direct link to support resources to improve user assistance.

- "Did you changed your mind? Let us know if you need clarifications: #{Azimutt.config(:contact_email)}"
+ "Did you change your mind? Let us know if you need further clarifications or assistance: #{Azimutt.config(:contact_email)}"
backend/lib/azimutt_web/templates/layout/_organization_left_bar.html.heex (1)

52-52: Verify dynamic display of plan badges.

The insertion of the plan_badge function call within a conditional block ensures that it is only rendered when not skipping the public site. This is a good use of dynamic content based on configuration, which can help in managing different deployment environments or configurations.

backend/lib/azimutt/services/cockpit_srv.ex (3)

Line range hint 45-65: Review handling of API response and system actions.

The handling of different API response scenarios using a cond block is well-implemented. The decision to stop the system based on a specific condition (res["stop"]) is a critical operation and should be carefully managed to avoid unintended shutdowns.


234-234: Ensure secure and accessible contact information display.

The method contact_us provides a direct email link for contact, which is a user-friendly way to offer support. Ensure that the email address is correctly configured and that the mailto link is accessible.


21-30: Ensure robust configuration checks and data sending.

The function check sends configuration data to an external server. The use of configuration values directly from Azimutt.config is appropriate here, ensuring that all necessary data is included in the request. However, ensure that sensitive data is not inadvertently being sent without proper security measures.

Verification successful

No sensitive data being sent to the cockpit service.

The verification process confirms that the code does not send sensitive data such as API keys, secrets, passwords, tokens, keys, or credentials via Azimutt.config. Thus, the implementation appears secure in this regard.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that sensitive data is not being sent to the cockpit service.
rg --type elixir $'Azimutt.config(:$$$)'

Length of output: 41



Script:

#!/bin/bash
# Description: Verify that sensitive data such as API keys or secrets are not being sent to the cockpit service.
rg --type elixir 'Azimutt.config(:api_key|:secret|:password|:token|:key|:credential)'

Length of output: 87

backend/lib/azimutt_web/templates/website/_footer.html.heex (1)

62-62: Validate the newly added email link.

The added line for the contact email appears correct and uses the newly introduced contact_email configuration. Please ensure that contact_email is appropriately configured in the environment settings and tested.

backend/lib/azimutt_web/templates/organization_member/index.html.heex (2)

17-39: Ensure accurate messaging and links for plan seat limits.

The conditional statements handle various scenarios regarding plan seats. It's essential to ensure that all links (e.g., contact us, adjust plan) are correctly set and that the messaging is clear and helpful to the user.

Verification successful

Ensure accurate messaging and links for plan seat limits.

The Routes.organization_billing_path is correctly defined and used in the application. The links in the specified file are correct, and the messaging appears to be clear and helpful.

  • backend/lib/azimutt_web/templates/organization_member/index.html.heex
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Check if the routes used in the links are correctly defined in the router.
rg 'Routes.organization_billing_path' backend/

Length of output: 5774


7-8: Review the logic handling organization member seats.

The logic for calculating max_seats, plan_seats, and used_seats is crucial for the correct display and functionality of the member management interface. Ensure that these calculations are accurate and reflect the actual constraints and limits set by the organization's plan.

Also applies to: 43-43

Verification successful

The logic handling organization member seats appears to be accurate.

The backend definitions and usages of Azimutt.limits and plan_seats align with the frontend logic in the template. No discrepancies were found.

  • Azimutt.limits is defined and used in backend/lib/azimutt/organizations/organization_plan.ex.
  • plan_seats is defined and used in multiple backend files, including backend/lib/azimutt/organizations/organization.ex and backend/lib/azimutt/organizations.ex.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the logic for calculating seats aligns with the backend calculations.
rg --type elixir 'Azimutt.limits().users' backend/

Length of output: 52



Script:

#!/bin/bash
# Search for the definition and usage of Azimutt.limits in the backend code
rg --type elixir 'Azimutt.limits' backend/

# Search for the definition and usage of plan_seats in the backend code
rg --type elixir 'plan_seats' backend/

Length of output: 6671

backend/lib/azimutt/admin.ex (1)

20-20: Approve the renaming of the function to count paid organizations.

The renaming of count_stripe_subscriptions to count_paid_organizations aligns with the broader refactoring goals of the PR. This change should make the function's purpose more clear and relevant to its actual functionality.

INSTALL.md (1)

Line range hint 158-217: Updated Environment Variables and Stripe Integration

The changes to the environment variables, especially around Stripe and email configurations, align well with the PR's objectives. The addition of STRIPE_PRICE_SOLO_MONTHLY, STRIPE_PRICE_SOLO_YEARLY, STRIPE_PRICE_TEAM_MONTHLY, STRIPE_PRICE_TEAM_YEARLY, and STRIPE_PRODUCT_ENTERPRISE supports the new pricing strategy.

Ensure that these variables are also updated in any deployment scripts or CI/CD configurations to avoid deployment issues.

Tools
LanguageTool

[grammar] ~209-~209: Did you mean “purchasing”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun. (ALLOW_TO)
Context: ...- STRIPE (optional): if true, allow to purchase plans with Stripe...

Markdownlint

210-210: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


211-211: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


212-212: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


213-213: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


214-214: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


215-215: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


216-216: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


217-217: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


219-219: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation


220-220: Expected: 2; Actual: 4 (MD007, ul-indent)
Unordered list indentation

Gitleaks

210-210: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data. (stripe-access-token)

backend/lib/azimutt.ex (2)

100-139: Review of Plan Limits Configuration

The updated limits for the Solo, Team, and Enterprise plans align with the new subscription strategy. It's important to ensure that these limits are enforced consistently in the application logic and that they match the user's expectations from the UI.


31-94: Review of Subscription Plans Configuration

The addition of Solo, Team, and Enterprise plans along with the updates to the Free and Pro plans are well-defined. It's crucial to ensure that these changes are reflected consistently across the frontend and any related services that utilize these plans.

Verification successful

Review of Subscription Plans Configuration

The search results indicate that the new plans (Solo, Team, Enterprise, Pro) and the updated Free plan are referenced consistently across the codebase, including business logic, UI components, and configuration files.

  • Business Logic: The plans are integrated into various modules, including organizations, projects, billing, and tracking.
  • UI Components: The plans are mentioned in multiple views and controllers, ensuring that the frontend reflects the different subscription tiers.
  • Configuration Files: The plans are also present in configuration and migration files, indicating proper setup and management.

This comprehensive integration suggests that the new plans are well-implemented and should function as intended across the application.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the new plans are consistently used across the frontend and related services.

# Test: Search for the usage of new plans in the frontend and related services.
rg --type elm --type js 'Solo|Team|Enterprise'

Length of output: 135



Script:

#!/bin/bash
# Description: Verify that the new plans are consistently used across the frontend and related services.

# Test: Search for the usage of all plans in the frontend and related services.
rg --type elm --type js 'free|solo|team|enterprise|pro'

Length of output: 270849



Script:

#!/bin/bash
# Description: Verify that the new plans are consistently used across business logic and UI components.

# Test: Search for the usage of all plans in business logic and UI components.
rg --type elixir --type js 'free|solo|team|enterprise|pro'

Length of output: 189724

backend/config/runtime.exs (2)

275-279: Approve new Stripe configuration settings.

The addition of new Stripe pricing plans and product configurations aligns with the PR objectives. Ensure that these settings are documented and that the use of System.fetch_env! is consistent across all environments.


36-39: Review email configuration fallbacks and ensure clarity in environment variable usage.

The chaining of environment variables for email settings (support_email and enterprise_support_email) increases complexity and can lead to configuration mistakes. Consider simplifying this approach or documenting the expected behavior clearly in the INSTALL.md or similar documentation.

backend/lib/azimutt_web/router.ex (1)

84-84: Review new routing for subscription plans.

The addition of a route for subscribing to plans with specific frequencies (/subscribe/:plan/:freq) is a significant change. Ensure that this route is properly secured and that the corresponding controller (SubscribeController) handles user input safely, especially since plan details are passed as URL parameters.

backend/lib/azimutt/tracking.ex (2)

129-133: Review new event logging for subscription initialization and start.

The addition of event logging for subscription initialization (subscribe_init) and start (subscribe_start) is crucial for auditing and analytics. Ensure that these events capture all necessary data points and are securely logged.


152-171: Ensure accurate and comprehensive logging for Stripe subscription events.

The addition of detailed Stripe event logging for subscription creation, deletion, and cancellation is important. Verify that all necessary data points are captured and that the logging mechanism is secure and efficient.

backend/lib/azimutt/organizations.ex (6)

43-44: Enhanced data preloading approved.

The additions of preloading clever_cloud_resource and heroku_resource improve data availability for organization management.


272-274: Refactored subscription retrieval looks good.

The implementation cleanly fetches and processes Stripe subscription data, improving maintainability.


283-284: Streamlined free trial activation approved.

The refactoring simplifies the activation of free trials, enhancing code clarity and reducing complexity.


408-417: Comprehensive plan validation logic approved.

The function effectively validates the organization's plan based on available resources and configurations, ensuring accurate plan settings.


419-436: Consistent plan validation for Clever Cloud and Heroku approved.

The functions handle plan validation consistently across Clever Cloud and Heroku resources, ensuring that the organization's plan is set accurately based on the available resources.

Also applies to: 438-455


458-478: Robust Stripe plan validation logic approved.

The function provides a detailed method for validating the organization's Stripe plan based on active subscriptions, handling various statuses and defaulting appropriately when no subscriptions are found.

backend/lib/azimutt_web/components/icon.ex (4)

47-47: Mapping of icon functions looks correct.

Ensure all functions referenced here are defined elsewhere in the codebase.


65-65: Icon function mappings are properly added.

Confirm that all functions like question_mark_circle, rectangle_group, etc., are defined and implemented correctly.


858-877: Review the new exclamation_triangle function for icon rendering.

The function correctly handles different icon styles based on the kind attribute. Ensure the SVG paths are accurate and visually correct in the UI.


1246-1265: Review the new question_mark_circle function for icon rendering.

This function also handles different styles based on the kind attribute effectively. Verify the SVG paths for visual accuracy.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Outside diff range and nitpick comments (1)
libs/models/src/legacy/legacyProject.ts (1)

Line range hint 916-918: Redundant else clause identified by static analysis.

The static analysis tool has identified an unnecessary else clause. This can be removed to simplify the code and improve readability.

- else {
-    // redundant else logic here
- }
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1e4a806 and 17bad45.

Files selected for processing (3)
  • backend/lib/azimutt_web/templates/organization/billing.html.heex (1 hunks)
  • frontend/src/Components/Slices/ProjectSaveDialogBody.elm (4 hunks)
  • libs/models/src/legacy/legacyProject.ts (1 hunks)
Additional context used
Biome
libs/models/src/legacy/legacyProject.ts

[error] 916-918: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)

Additional comments not posted (3)
backend/lib/azimutt_web/templates/organization/billing.html.heex (2)

24-38: Legacy plan warning message handling.

This section effectively informs users about legacy plans and encourages them to migrate. Ensure that the migration steps are clear and that the provided link is always accessible and correct.

Consider adding more detailed instructions or a help link for users who might need assistance during the migration process.


3-8: Ensure dynamic email retrieval is secure and robust.

The use of Azimutt.config(:enterprise_support_email) to dynamically fetch the email address is efficient. However, ensure that this method handles cases where the configuration might not be set, to avoid displaying broken links or incorrect information.

Verification successful

The Azimutt.config method handles null or undefined values gracefully by providing a default value.

  • The method config(key, default \\ nil) in backend/lib/azimutt.ex uses Application.get_env/3, which returns the provided default value if the configuration is not set.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that Azimutt.config method handles null or undefined values gracefully.

# Test: Search for the Azimutt.config implementation. Expect: Proper null checks and default values handling.
rg --type elixir $'def config'

Length of output: 283



Script:

#!/bin/bash
# Extract the implementation of the config methods in backend/lib/azimutt.ex
ast-grep --lang elixir --pattern $'def config($_) do\n  $$$\nend' --pattern $'def config($_, $_) do\n  $$$\nend'

Length of output: 275



Script:

#!/bin/bash
# Extract the implementation of the config methods in backend/lib/azimutt.ex
ast-grep --lang elixir --pattern $'def config($_) do\n  $$$\nend' backend/lib/azimutt.ex
ast-grep --lang elixir --pattern $'def config($_, $_) do\n  $$$\nend' backend/lib/azimutt.ex

Length of output: 179



Script:

#!/bin/bash
# Extract the implementation of the config methods in backend/lib/azimutt.ex
rg -A 10 'def config' backend/lib/azimutt.ex

Length of output: 663

frontend/src/Components/Slices/ProjectSaveDialogBody.elm (1)

196-200: Radio button component for project storage options.

This component allows users to choose between saving projects locally or remotely. It's implemented well with clear and concise code. Ensure that the storageToString function handles all possible cases to prevent runtime errors.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

Outside diff range and nitpick comments (2)
libs/connector-oracle/README.md (2)

Line range hint 3-3: Improve clarity in the introductory sentence.

The phrase "This library allows to connect to [Oracle]" could be improved for grammatical correctness and clarity.

- This library allows to connect to [Oracle]
+ This library allows users to connect to [Oracle]
Tools
LanguageTool

[style] ~10-~10: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...the gateway server. **Feel free to use it and even submit PR to improve it...

(FEEL_FREE_TO_STYLE_ME)


Line range hint 5-5: Correct verb agreement.

The phrase "It lists all schemas, tables, columns, relations and types and format them in a JSON Schema." has a verb agreement error.

- It lists all schemas, tables, columns, relations and types and format them in a JSON Schema.
+ It lists all schemas, tables, columns, relations, and types and formats them in a JSON Schema.
Tools
LanguageTool

[style] ~10-~10: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...the gateway server. **Feel free to use it and even submit PR to improve it...

(FEEL_FREE_TO_STYLE_ME)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 17bad45 and e734b1e.

Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
Files selected for processing (30)
  • app.json (2 hunks)
  • cli/.gitignore (1 hunks)
  • cli/.npmignore (1 hunks)
  • cli/html-report/README.md (2 hunks)
  • cli/html-report/app/globals.css (1 hunks)
  • cli/html-report/components.json (1 hunks)
  • cli/html-report/report.html (1 hunks)
  • cli/html-report/src/components/report/ReportStats/ReportStatsGrid.tsx (1 hunks)
  • cli/html-report/tailwind.config.js (1 hunks)
  • cli/src/analyze.ts (1 hunks)
  • cli/src/utils/file.ts (1 hunks)
  • gateway/package.json (1 hunks)
  • heroku.yml (1 hunks)
  • libs/connector-oracle/README.md (1 hunks)
  • libs/connector-oracle/src/connect.test.ts (1 hunks)
  • libs/connector-oracle/src/connect.ts (1 hunks)
  • libs/connector-oracle/src/helpers.test.ts (1 hunks)
  • libs/connector-oracle/src/helpers.ts (1 hunks)
  • libs/connector-oracle/src/history.test.ts (1 hunks)
  • libs/connector-oracle/src/history.ts (1 hunks)
  • libs/connector-oracle/src/index.ts (1 hunks)
  • libs/connector-oracle/src/integration.test.ts (1 hunks)
  • libs/connector-oracle/src/oracle.test.ts (1 hunks)
  • libs/connector-oracle/src/oracle.ts (1 hunks)
  • libs/connector-oracle/src/query.ts (1 hunks)
  • libs/connector-oracle/src/stats.test.ts (1 hunks)
  • libs/connector-oracle/src/stats.ts (1 hunks)
  • libs/models/src/analyze/rule.ts (3 hunks)
  • libs/models/src/databaseUrl.test.ts (1 hunks)
  • libs/models/src/databaseUrl.ts (3 hunks)
Files skipped from review due to trivial changes (18)
  • cli/.gitignore
  • cli/.npmignore
  • cli/html-report/README.md
  • cli/html-report/app/globals.css
  • cli/html-report/components.json
  • cli/html-report/report.html
  • cli/html-report/src/components/report/ReportStats/ReportStatsGrid.tsx
  • cli/html-report/tailwind.config.js
  • gateway/package.json
  • heroku.yml
  • libs/connector-oracle/src/connect.test.ts
  • libs/connector-oracle/src/helpers.test.ts
  • libs/connector-oracle/src/helpers.ts
  • libs/connector-oracle/src/history.ts
  • libs/connector-oracle/src/integration.test.ts
  • libs/connector-oracle/src/oracle.test.ts
  • libs/connector-oracle/src/stats.test.ts
  • libs/models/src/analyze/rule.ts
Additional context used
Biome
libs/connector-oracle/src/query.ts

[error] 27-29: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)


[error] 10-10: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

cli/src/analyze.ts

[error] 126-132: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)


[error] 130-132: This else clause can be omitted because previous branches break early.

(lint/style/noUselessElse)


[error] 133-136: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)


[error] 143-149: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)


[error] 147-149: This else clause can be omitted because previous branches break early.

(lint/style/noUselessElse)


[error] 159-164: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)

libs/connector-oracle/src/oracle.ts

[error] 68-68: Avoid the use of spread (...) syntax on accumulators.

Spread syntax should be avoided on accumulators (like those in .reduce) because it causes a time complexity of O(n^2).
Consider methods such as .splice or .push instead.

(lint/performance/noAccumulatingSpread)

LanguageTool
libs/connector-oracle/README.md

[grammar] ~3-~3: Did you mean “connecting”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...# Oracle connector This library allows to connect to [Oracle](https://www.oracle.com/data...

(ALLOW_TO)


[uncategorized] ~5-~5: This verb does not appear to agree with the subject. Consider using a different form.
Context: ...ables, columns, relations and types and format them in a JSON Schema. This library is...

(AI_EN_LECTOR_REPLACEMENT_VERB_AGREEMENT)


[style] ~10-~10: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...the gateway server. **Feel free to use it and even submit PR to improve it...

(FEEL_FREE_TO_STYLE_ME)

Additional comments not posted (4)
cli/src/utils/file.ts (1)

2-2: Ensure consistent import usage.

Consider using destructuring for all imports from node:path and node:url for consistency and clarity.

- import {dirname} from "node:path";
- import {fileURLToPath} from "node:url";
+ import { dirname, fileURLToPath } from "node:url";
app.json (1)

26-37: Review newly added environment variables for clarity and necessity.

The additions of SECRET_KEY_BASE and AUTH_PASSWORD are crucial for security and functionality. Ensure their descriptions are clear and they are properly secured in the environment.

libs/connector-oracle/src/index.ts (1)

24-43: Review the configuration of the Oracle connector.

The setup for the Oracle connector includes methods for schema retrieval, query execution, and statistics gathering. Ensure that these methods are correctly implemented and the promises are properly handled.

libs/connector-oracle/README.md (1)

10-10: Consider rephrasing for a more professional tone.

The phrase "Feel free to use it and even submit PR to improve it:" could be rephrased for a more professional tone.

- Feel free to use it and even submit PR to improve it:
+ You are welcome to use this library and contribute by submitting PRs:
Tools
LanguageTool

[style] ~10-~10: The phrase ‘feel free to’ is used quite frequently. Consider using a less frequent alternative to set your writing apart from others and make it sound more professional.
Context: ...the gateway server. **Feel free to use it and even submit PR to improve it...

(FEEL_FREE_TO_STYLE_ME)

cli/src/analyze.ts Show resolved Hide resolved
cli/src/analyze.ts Show resolved Hide resolved
libs/connector-oracle/src/history.test.ts Show resolved Hide resolved
libs/connector-oracle/src/connect.ts Show resolved Hide resolved
libs/connector-oracle/src/query.ts Show resolved Hide resolved
libs/connector-oracle/src/stats.ts Show resolved Hide resolved
libs/connector-oracle/src/stats.ts Show resolved Hide resolved
libs/connector-oracle/src/oracle.ts Show resolved Hide resolved
libs/models/src/databaseUrl.ts Show resolved Hide resolved
libs/models/src/databaseUrl.test.ts Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

Outside diff range and nitpick comments (1)
frontend/src/PagesComponents/Organization_/Project_/Models/Erd.elm (1)

Line range hint 208-212: Improve readability by breaking down nested calls.

The nested calls make the function harder to read. Consider breaking them down for better readability.

canShowTables : Int -> Maybe Erd -> Bool
canShowTables nb erd =
    let
        organization = erd |> getOrganizationM Nothing
        plan = organization.plan
        maxTables = plan.layoutTables
        layoutTables = erd |> Maybe.mapOrElse (currentLayout >> .tables >> List.length) 0
    in
    Maybe.all (\max -> layoutTables + nb <= max) maxTables
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e734b1e and 24d0768.

Files selected for processing (26)
  • backend/lib/azimutt.ex (1 hunks)
  • backend/lib/azimutt/organizations.ex (5 hunks)
  • backend/lib/azimutt/organizations/organization/data.ex (1 hunks)
  • backend/lib/azimutt/organizations/organization_plan.ex (1 hunks)
  • backend/lib/azimutt/projects.ex (1 hunks)
  • frontend/src/Components/Slices/ExportDialogBody.elm (4 hunks)
  • frontend/src/Components/Slices/NewLayoutBody.elm (1 hunks)
  • frontend/src/Components/Slices/ProPlan.elm (17 hunks)
  • frontend/src/Components/Slices/ProjectSaveDialogBody.elm (6 hunks)
  • frontend/src/Conf.elm (2 hunks)
  • frontend/src/Models/Feature.elm (1 hunks)
  • frontend/src/Models/Organization.elm (2 hunks)
  • frontend/src/Models/Plan.elm (1 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Components/ProjectSharing.elm (3 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Models/Erd.elm (1 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Updates.elm (4 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Updates/Groups.elm (3 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Updates/Memo.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/NewLayout.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnRelations.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/RelationMissing.elm (2 hunks)
  • frontend/src/Track.elm (3 hunks)
  • frontend/tests/TestHelpers/OrganizationFuzzers.elm (1 hunks)
  • libs/models/src/legacy/legacyProject.test.ts (1 hunks)
  • libs/models/src/legacy/legacyProject.ts (1 hunks)
Files not reviewed due to errors (1)
  • frontend/src/Track.elm (no review received)
Files skipped from review due to trivial changes (3)
  • backend/lib/azimutt/organizations/organization/data.ex
  • frontend/src/Models/Feature.elm
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/RelationMissing.elm
Files skipped from review as they are similar to previous changes (1)
  • frontend/src/Components/Slices/ProjectSaveDialogBody.elm
Additional context used
Biome
libs/models/src/legacy/legacyProject.ts

[error] 920-922: This else clause can be omitted because previous branches break early.

Unsafe fix: Omit the else clause.

(lint/style/noUselessElse)

Additional comments not posted (54)
backend/lib/azimutt/organizations/organization_plan.ex (2)

19-23: Ensure consistency in naming conventions.

The field projects is still present, but project_dbs and project_layouts are introduced. Consider renaming projects to project_dbs for consistency.

-    field :projects, integer() | nil
+    field :project_dbs, integer() | nil

11-16: Review new fields for correctness and completeness.

The new fields added seem relevant to the organization plans. Ensure that these fields are correctly used and validated in other parts of the codebase.

Verification successful

Review new fields for correctness and completeness.

The new fields data_exploration, colors, aml, schema_export, ai, and analysis are correctly used and validated in the codebase. They appear in various places, including the main organization module and configuration files, indicating proper integration.

  • backend/lib/azimutt/organizations/organization.ex
  • backend/lib/azimutt.ex
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the new fields are correctly used and validated in the codebase.

# Test: Search for the usage of the new fields. Expect: Correct usage and validation.
rg --type elixir $'data_exploration|colors|aml|schema_export|ai|analysis'

Length of output: 71097

frontend/tests/TestHelpers/OrganizationFuzzers.elm (1)

37-37: Review updated plan fuzzer for correctness.

The plan fuzzer now includes more fields. Ensure that the fields match the Plan model and are correctly used in tests.

Verification successful

Review updated plan fuzzer for correctness.

The plan fuzzer includes more fields that match the Plan model. The fields are correctly aligned with the Plan model, ensuring consistency and correctness in the tests.

  • planId corresponds to id
  • planName corresponds to name
  • Fuzz.bool corresponds to dataExploration
  • Fuzz.bool corresponds to colors
  • Fuzz.bool corresponds to aml
  • Fuzz.bool corresponds to schemaExport
  • Fuzz.bool corresponds to ai
  • stringSmall corresponds to analysis
  • Fuzz.bool corresponds to projectExport

All fields are correctly used in the plan fuzzer.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the updated `plan` fuzzer fields match the `Plan` model and are correctly used in tests.

# Test: Search for the usage of the updated `plan` fuzzer. Expect: Correct usage in tests.
rg --type elm $'planId|planName|Fuzz.bool|stringSmall|intPosSmall'

Length of output: 4781



Script:

#!/bin/bash
# Description: Verify that the fields in the `plan` fuzzer match the `Plan` model.

# Locate the definition of the `Plan` model.
rg --type elm 'type alias Plan' 

Length of output: 80



Script:

#!/bin/bash
# Description: Extract the full definition of the `Plan` model from the `frontend/src/Models/Plan.elm` file.

# Retrieve the definition of the `Plan` model.
rg --type elm --context 10 'type alias Plan' frontend/src/Models/Plan.elm

Length of output: 658

frontend/src/Models/Plan.elm (4)

36-48: LGTM!

The encoding logic for the new fields looks correct.


55-70: LGTM!

The decoding logic for the new fields looks correct.


74-92: LGTM!

The sample plan values for the new fields look correct.


7-26: Ensure Synchronization with Backend and Legacy Models

The Plan type alias has new fields added. Ensure that the Plan definition remains in sync with libs/models/src/legacy/legacyProject.ts and backend/lib/azimutt/organizations/organization_plan.ex as mentioned in the comment.

Verification successful

Ensure Synchronization with Backend and Legacy Models

The Plan type alias in frontend/src/Models/Plan.elm is in sync with the definitions in backend/lib/azimutt/organizations/organization_plan.ex and libs/models/src/legacy/legacyProject.ts. All fields match across the files.

  • frontend/src/Models/Plan.elm:

    type alias Plan =
        { id : String
        , name : String
        , dataExploration : Bool
        , colors : Bool
        , aml : Bool
        , schemaExport : Bool
        , ai : Bool
        , analysis : String
        , projectExport : Bool
        , projects : Maybe Int
        , projectDbs : Maybe Int
        , projectLayouts : Maybe Int
        , layoutTables : Maybe Int
        , projectDoc : Maybe Int
        , projectShare : Bool
        }
  • backend/lib/azimutt/organizations/organization_plan.ex:

    typedstruct enforce: true do
      field :id, atom()
      field :name, String.t()
      field :data_exploration, boolean()
      field :colors, boolean()
      field :aml, boolean()
      field :schema_export, boolean()
      field :ai, boolean()
      field :analysis, String.t()
      field :project_export, boolean()
      field :projects, integer() | nil
      field :project_dbs, integer() | nil
      field :project_layouts, integer() | nil
      field :layout_tables, integer() | nil
      field :project_doc, integer() | nil
      field :project_share, boolean()
      field :streak, integer()
    end
  • libs/models/src/legacy/legacyProject.ts:

    export interface LegacyPlan {
        id: LegacyPlanId
        name: string
        data_exploration: boolean
        colors: boolean
        aml: boolean
        schema_export: boolean
        ai: boolean
        analysis: string
        project_export: boolean
        projects: number | null
        project_dbs: number | null
        project_layouts: number | null
        layout_tables: number | null
        project_doc: number | null
        project_share: boolean
        streak: number
    }
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify synchronization of Plan definition with backend and legacy models.

# Test: Check for the Plan definition in the backend and legacy models. Expect: Definitions to be in sync.
rg --type js --type elixir $'Plan'

Length of output: 1759



Script:

#!/bin/bash
# Extract the Plan definition from the Elixir file
echo "### Elixir Plan Definition ###"
rg --type elixir 'defmodule Azimutt.Organizations.OrganizationPlan do' -A 30 backend/lib/azimutt/organizations/organization_plan.ex

# Extract the Plan definition from the TypeScript file
echo "### TypeScript Plan Definition ###"
rg --type js 'type Plan =' -A 30 libs/models/src/legacy/legacyProject.ts

Length of output: 1202



Script:

#!/bin/bash
# Extract the Plan definition from the TypeScript file with a broader search pattern
echo "### TypeScript Plan Definition ###"
rg --type js 'Plan' -A 50 libs/models/src/legacy/legacyProject.ts

Length of output: 4196

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/NewLayout.elm (1)

59-59: Ensure Proper Handling of Feature Limits

The update function now includes logic to handle the projectLayouts feature limit. Ensure that the ProPlan.layoutsModalBody and Track.planLimit functions are correctly implemented to handle feature limits.

Verification successful

Ensure Proper Handling of Feature Limits

The update function now includes logic to handle the projectLayouts feature limit. Both ProPlan.layoutsModalBody and Track.planLimit functions are correctly implemented to handle feature limits and modal display.

  • Track.planLimit sends an event with the plan and feature information, ensuring the feature limits are correctly handled.
  • ProPlan.layoutsModalBody constructs the modal body for layouts with the appropriate HTML structure.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify implementation of ProPlan.layoutsModalBody and Track.planLimit functions.

# Test: Check for the implementations of ProPlan.layoutsModalBody and Track.planLimit. Expect: Correct handling of feature limits.
rg --type elm $'layoutsModalBody|planLimit'

Length of output: 4704



Script:

#!/bin/bash
# Extract the implementation of the planLimit function from Track.elm
ast-grep --lang elm --pattern 'planLimit : $_ -> $_ -> $_' --pattern 'planLimit $_ =' frontend/src/Track.elm

# Extract the implementation of the layoutsModalBody function from ProPlan.elm
ast-grep --lang elm --pattern 'layoutsModalBody : $_ -> $_ -> $_' --pattern 'layoutsModalBody $_ =' frontend/src/Components/Slices/ProPlan.elm

Length of output: 469



Script:

#!/bin/bash
# Use ripgrep to search for the implementation of the planLimit function in Track.elm
rg 'planLimit' frontend/src/Track.elm

# Use ripgrep to search for the implementation of the layoutsModalBody function in ProPlan.elm
rg 'layoutsModalBody' frontend/src/Components/Slices/ProPlan.elm

Length of output: 1688



Script:

#!/bin/bash
# Use ripgrep to search for the full implementation of the planLimit function in Track.elm with more context lines
rg 'planLimit' -A 10 frontend/src/Track.elm

# Use ripgrep to search for the full implementation of the layoutsModalBody function in ProPlan.elm with more context lines
rg 'layoutsModalBody' -A 10 frontend/src/Components/Slices/ProPlan.elm

Length of output: 4576

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnRelations.elm (1)

65-65: Ensure Proper Handling of Analysis Feature

The view function now includes logic to handle the analysis feature. Ensure that the ProPlan.analysisResults function is correctly implemented to handle analysis results.

Verification successful

Ensure Proper Handling of Analysis Feature

The view function now includes logic to handle the analysis feature. The ProPlan.analysisResults function correctly implements the logic to handle analysis results based on the project's analysis plan and item count.

  • frontend/src/Components/Slices/ProPlan.elm: Implementation of ProPlan.analysisResults is correct.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify implementation of ProPlan.analysisResults function.

# Test: Check for the implementation of ProPlan.analysisResults. Expect: Correct handling of analysis results.
rg --type elm $'analysisResults'

Length of output: 2351



Script:

#!/bin/bash
# Description: Retrieve the implementation of ProPlan.analysisResults function.

# Extract the implementation of the analysisResults function from the ProPlan module.
ast-grep --lang elm --pattern $'analysisResults : $_\nanalysisResults $_ = $_' frontend/src/Components/Slices/ProPlan.elm

Length of output: 228



Script:

#!/bin/bash
# Description: Retrieve the implementation of ProPlan.analysisResults function.

# Search for the definition of the analysisResults function in the ProPlan module.
rg 'analysisResults' -A 10 frontend/src/Components/Slices/ProPlan.elm

Length of output: 1527

frontend/src/PagesComponents/Organization_/Project_/Updates/Memo.elm (2)

74-74: LGTM!

The plan limit tracking logic for Feature.projectDoc looks correct.


9-9: Verify usage of the new import.

Ensure that the new import Models.Feature as Feature is utilized in the file.

Verification successful

The new import Models.Feature as Feature is utilized within the file.

  • The usage of Feature is confirmed in the context of Track.planLimit Feature.projectDoc.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the usage of the new import `Models.Feature as Feature`.

# Test: Search for the usage of `Feature` within this file.
rg --type elm $'Feature' frontend/src/PagesComponents/Organization_/Project_/Updates/Memo.elm

Length of output: 295

frontend/src/PagesComponents/Organization_/Project_/Updates/Groups.elm (3)

106-106: LGTM!

The plan limit tracking logic for Feature.projectDoc looks correct.


133-133: LGTM!

The plan limit tracking logic for Feature.colors looks correct.


10-10: Verify usage of the new import.

Ensure that the new import Models.Feature as Feature is utilized in the file.

Verification successful

Verified usage of the new import.

The new import Models.Feature as Feature is utilized in the file in two different contexts, confirming its necessity.

  • Usage in model.erd |> Maybe.map (\erd -> [ erd |> Erd.getProjectRef urlInfos |> ProPlan.groupsModalBody |> CustomModalOpen |> T.send, Track.planLimit Feature.projectDoc (Just erd) ]) |> Extra.cmdML
  • Usage in Extra.cmdL [ ProPlan.colorsModalBody project ProPlanColors ProPlan.colorsInit |> CustomModalOpen |> T.send, Track.planLimit Feature.colors model.erd ]
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the usage of the new import `Models.Feature as Feature`.

# Test: Search for the usage of `Feature` within this file.
rg --type elm $'Feature' frontend/src/PagesComponents/Organization_/Project_/Updates/Groups.elm

Length of output: 505

frontend/src/Components/Slices/NewLayoutBody.elm (1)

72-72: LGTM!

The plan limit checking logic for projectLayouts looks correct.

frontend/src/Conf.elm (1)

1-1: Expose schema in module declaration.

The module declaration now exposes schema, which is useful for external access.

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis.elm (2)

16-16: Import Models.Feature

The import statement for Models.Feature is added, which is necessary for the new condition in the viewSchemaAnalysis function.


Line range hint 65-70: Conditionally render analysis warning.

The viewSchemaAnalysis function now includes a condition to render an analysis warning based on the project.organization.plan.analysis value. Ensure that this condition is correctly integrated and tested.

backend/lib/azimutt/projects.ex (1)

223-223: Update project access condition.

The access_project function now includes a condition to check the project_share value from the organization's plan. Ensure this condition is correctly integrated and tested.

libs/models/src/legacy/legacyProject.test.ts (1)

27-39: LGTM!

The new properties align with the updated plan features. Ensure that these properties are correctly integrated and tested throughout the codebase.

backend/lib/azimutt.ex (2)

97-97: LGTM!

The new active_plans function returns a list of active plans. Ensure that this function is correctly integrated and used throughout the codebase.


100-147: LGTM!

The new feature limits align with the updated plan features. Ensure that these feature limits are correctly integrated and used throughout the codebase.

Verification successful

LGTM!

The new feature limits align with the updated plan features. The shell script results confirm that these feature limits are correctly integrated and used throughout the codebase, particularly in the backend/lib/azimutt/organizations.ex file.

  • backend/lib/azimutt/organizations.ex: Lines referencing new feature limits such as schema_exploration, data_exploration, colors, aml, schema_export, ai, analysis, project_export, users, projects, project_dbs, project_layouts, layout_tables, project_doc, project_share, api, sso, user_rights, gateway_custom, billing, support_on_premise, support_enterprise, consulting, and roadmap.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the integration of new feature limits.

# Test: Search for the usage of the new feature limits. Expect: Correct integration and usage.
rg --type elixir 'schema_exploration|data_exploration|colors|aml|schema_export|ai|analysis|project_export|users|projects|project_dbs|project_layouts|layout_tables|project_doc|project_share|api|sso|user_rights|gateway_custom|billing|support_on_premise|support_enterprise|consulting|roadmap'

Length of output: 113180

frontend/src/Components/Slices/ExportDialogBody.elm (2)

124-139: LGTM!

The updates to the getOutput function align with the updated plan features. Ensure that the new check for schemaExport is correctly integrated and used.

Verification successful

Verified Integration of schemaExport Check

The schemaExport check is correctly integrated and used across the codebase, including the ExportDialogBody.elm file. The changes align with the updated plan features.

  • frontend/src/Components/Slices/ExportDialogBody.elm
  • frontend/src/Models/Plan.elm
  • frontend/src/Models/Feature.elm
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the integration of the new check for `schemaExport` in the `erd` object.

# Test: Search for the usage of the `schemaExport` check. Expect: Correct integration and usage.
rg --type elm 'schemaExport'

Length of output: 1443


32-32: LGTM!

The import modification aligns with the updated plan features. Ensure that the Models.Feature module is correctly used.

Verification successful

Verified Usage of Models.Feature Module

The Models.Feature module is correctly imported and utilized within ExportDialogBody.elm.

  • ExportDialogBody.elm: The Feature alias is used in Track.planLimit Feature.schemaExport (Just erd).
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the usage of the `Models.Feature` module.

# Test: Search for the usage of the `Models.Feature` module. Expect: Correct integration and usage.
rg --type elm 'Models.Feature'

Length of output: 1498



Script:

#!/bin/bash
# Description: Verify the usage of the `Models.Feature` module in ExportDialogBody.elm.

# Test: Search for the usage of the `Feature` alias within ExportDialogBody.elm. Expect: Correct integration and usage.
rg 'Feature' frontend/src/Components/Slices/ExportDialogBody.elm

Length of output: 345

backend/lib/azimutt/organizations.ex (3)

43-44: LGTM!


272-274: LGTM!


283-284: LGTM!

frontend/src/Components/Slices/ProPlan.elm (16)

61-61: Use of Maybe.withDefault for plan projects

Ensure that project.organization.plan.projects is correctly handled and defaults to Feature.projects.default if Nothing.


70-70: Ensure URL correctness

Verify that the URL generated for the primary link is correct and properly handles the Feature.projects.name.


88-88: Ensure URL correctness

Verify that the URL generated for the secondary link is correct and properly handles the Feature.projectLayouts.name.


104-104: Ensure URL correctness

Verify that the URL generated for the primary link is correct and properly handles the Feature.projectLayouts.name.


113-113: Use of Maybe.withDefault for layout tables

Ensure that project.organization.plan.layoutTables is correctly handled and defaults to Feature.layoutTables.default if Nothing.


122-122: Ensure URL correctness

Verify that the URL generated for the primary link is correct and properly handles the Feature.layoutTables.name.


131-131: Use of Maybe.withDefault for project documentation

Ensure that project.organization.plan.projectDoc is correctly handled and defaults to Feature.memos.default if Nothing.


140-140: Ensure URL correctness

Verify that the URL generated for the primary link is correct and properly handles the Feature.memos.name.


149-149: Use of Maybe.withDefault for project documentation

Ensure that project.organization.plan.projectDoc is correctly handled and defaults to Feature.groups.default if Nothing.


158-158: Ensure URL correctness

Verify that the URL generated for the primary link is correct and properly handles the Feature.groups.name.


248-248: Ensure URL correctness

Verify that the URL generated for the primary link is correct and properly handles the Feature.colors.name.


332-332: Ensure URL correctness

Verify that the URL generated for the secondary link is correct and properly handles the Feature.projectShare.name.


347-347: Ensure URL correctness

Verify that the URL generated for the secondary link is correct and properly handles the Feature.schemaExport.name.


364-364: Ensure URL correctness

Verify that the URL generated for the secondary link is correct and properly handles the Feature.analysis.name.


373-373: Check feature limits

Ensure that the condition project.organization.plan.analysis /= Feature.analysis.preview correctly handles the feature limits.


390-390: Ensure URL correctness

Verify that the URL generated for the secondary link is correct and properly handles the Feature.analysis.name.

frontend/src/PagesComponents/Organization_/Project_/Components/ProjectSharing.elm (3)

151-151: Ensure correct plan validation

Ensure that erd |> Erd.getOrganizationM Nothing |> .plan |> .projectShare correctly validates the plan for project sharing.


155-155: Track plan limit

Verify that Track.planLimit Feature.projectShare erd correctly tracks the plan limit for project sharing.


371-371: Ensure correct plan validation

Ensure that project.organization.plan.projectShare correctly validates the plan for project sharing.

libs/models/src/legacy/legacyProject.ts (3)

592-604: LGTM!

The Zod schema for LegacyPlan matches the interface definition and looks good.


573-585: Ensure consistency between interface and Zod schema.

The LegacyPlan interface has been updated with new fields. Ensure that the Zod schema matches the interface definition.

Verification successful

Consistency between interface and Zod schema verified.

The LegacyPlan interface and the corresponding Zod schema definitions are consistent and match each other.

  • libs/models/src/legacy/legacyProject.ts:
    • interface LegacyPlan
    • const LegacyPlan = z.object({...}).strict()
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify consistency between `LegacyPlan` interface and Zod schema.

# Test: Compare the interface and Zod schema definitions. Expect: Both definitions to match.
ast-grep --lang typescript --pattern $'interface LegacyPlan {
  id: LegacyPlanId
  name: string
  data_exploration: boolean
  colors: boolean
  aml: boolean
  schema_export: boolean
  ai: boolean
  analysis: string
  project_export: boolean
  projects: number | null
  project_dbs: number | null
  project_layouts: number | null
  layout_tables: number | null
  project_doc: number | null
  project_share: boolean
  streak: number
}' libs/models/src/legacy/legacyProject.ts

ast-grep --lang typescript --pattern $'const LegacyPlan = z.object({
  id: LegacyPlanId,
  name: z.string(),
  data_exploration: z.boolean(),
  colors: z.boolean(),
  aml: z.boolean(),
  schema_export: z.boolean(),
  ai: z.boolean(),
  analysis: z.string(),
  project_export: z.boolean(),
  projects: z.number().nullable(),
  project_dbs: z.number().nullable(),
  project_layouts: z.number().nullable(),
  layout_tables: z.number().nullable(),
  project_doc: z.number().nullable(),
  project_share: z.boolean(),
  streak: z.number(),
}).strict()' libs/models/src/legacy/legacyProject.ts

Length of output: 3625


566-567: Verify the necessity of the pro plan.

The LegacyPlanId type includes a pro plan, but it is not mentioned in the AI-generated summary. Verify if the pro plan is required and used elsewhere in the codebase.

frontend/src/PagesComponents/Organization_/Project_/Updates.elm (5)

26-26: LGTM!

The import statement for Models.Feature is correctly added.


143-143: LGTM!

The changes to the ShowTables function correctly handle plan-based restrictions using ProPlan.layoutTablesModalBody and Track.planLimit.


150-150: LGTM!

The changes to the ShowAllTables function correctly handle plan-based restrictions using ProPlan.layoutTablesModalBody and Track.planLimit.


268-268: LGTM!

The changes to the TableColor function correctly handle plan-based restrictions using ProPlan.colorsModalBody and Track.planLimit.

Verification successful

LGTM!
The changes to the TableColor function correctly handle plan-based restrictions using ProPlan.colorsModalBody and Track.planLimit. Both functions are appropriately implemented to manage their respective tasks.

  • ProPlan.colorsModalBody constructs a modal body indicating a Pro feature.
  • Track.planLimit sends an event to track plan limits.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correctness of ProPlan.colorsModalBody and Track.planLimit.

# Test: Search for the function definitions. Expect: Definitions of both functions.
rg --type elm 'ProPlan.colorsModalBody'
rg --type elm 'Track.planLimit'

Length of output: 3695



Script:

#!/bin/bash
# Search for the definition of the ProPlan.colorsModalBody function
rg --type elm 'colorsModalBody' -g '*.elm'

# Search for the definition of the Track.planLimit function
rg --type elm 'planLimit' -g '*.elm'

Length of output: 5851



Script:

#!/bin/bash
# Extract the implementation of the ProPlan.colorsModalBody function
rg --type elm --context 10 'colorsModalBody' frontend/src/Components/Slices/ProPlan.elm

# Extract the implementation of the Track.planLimit function
rg --type elm --context 10 'planLimit' frontend/src/Track.elm

Length of output: 6449


136-136: LGTM!

The changes to the ShowTable function correctly handle plan-based restrictions using ProPlan.layoutTablesModalBody and Track.planLimit.

Verification successful

LGTM!

The changes to the ShowTable function correctly handle plan-based restrictions using ProPlan.layoutTablesModalBody and Track.planLimit. Both functions are properly defined and their usage is appropriate.

  • ProPlan.layoutTablesModalBody constructs the modal body based on the project reference.
  • Track.planLimit sends an event to track plan limits based on the feature and project details.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the correctness of ProPlan.layoutTablesModalBody and Track.planLimit.

# Test: Search for the function definitions. Expect: Definitions of both functions.
rg --type elm 'ProPlan.layoutTablesModalBody'
rg --type elm 'Track.planLimit'

Length of output: 3934



Script:

#!/bin/bash
# Description: Find the definitions of ProPlan.layoutTablesModalBody and Track.planLimit.

# Search for the definition of ProPlan.layoutTablesModalBody
rg --type elm 'layoutTablesModalBody' -g '*.elm'

# Search for the definition of Track.planLimit
rg --type elm 'planLimit' -g '*.elm'

Length of output: 5789



Script:

#!/bin/bash
# Extract the definition of ProPlan.layoutTablesModalBody from ProPlan.elm
ast-grep --lang elm --pattern 'layoutTablesModalBody : $_' --pattern 'layoutTablesModalBody $_ = $_' frontend/src/Components/Slices/ProPlan.elm

# Extract the definition of Track.planLimit from Track.elm
ast-grep --lang elm --pattern 'planLimit : $_' --pattern 'planLimit $_ = $_' frontend/src/Track.elm

Length of output: 461



Script:

#!/bin/bash
# Extract the definition of ProPlan.layoutTablesModalBody from ProPlan.elm
rg --no-heading --line-number --context 5 'layoutTablesModalBody' frontend/src/Components/Slices/ProPlan.elm

# Extract the definition of Track.planLimit from Track.elm
rg --no-heading --line-number --context 5 'planLimit' frontend/src/Track.elm

Length of output: 4605

Comment on lines 196 to 198
erd |> getOrganizationM Nothing |> .plan |> .projectDoc |> Maybe.all (\max -> max > List.length (erd |> Maybe.mapOrElse (currentLayout >> .memos) []))


Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve readability by breaking down nested calls.

The nested calls make the function harder to read. Consider breaking them down for better readability.

canCreateMemo : Maybe Erd -> Bool
canCreateMemo erd =
    let
        organization = erd |> getOrganizationM Nothing
        plan = organization.plan
        maxMemos = plan.projectDoc
        currentMemos = erd |> Maybe.mapOrElse (currentLayout >> .memos) [] |> List.length
    in
    Maybe.all (\max -> max > currentMemos) maxMemos

Comment on lines 201 to 203
erd |> getOrganizationM Nothing |> .plan |> .projectDoc |> Maybe.all (\max -> max > List.length (erd |> Maybe.mapOrElse (currentLayout >> .groups) []))


Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve readability by breaking down nested calls.

The nested calls make the function harder to read. Consider breaking them down for better readability.

canCreateGroup : Maybe Erd -> Bool
canCreateGroup erd =
    let
        organization = erd |> getOrganizationM Nothing
        plan = organization.plan
        maxGroups = plan.projectDoc
        currentGroups = erd |> Maybe.mapOrElse (currentLayout >> .groups) [] |> List.length
    in
    Maybe.all (\max -> max > currentGroups) maxGroups

Comment on lines 31 to 94
name: "Free",
description: "Quickly explore your db with one command. No long term save.",
monthly: "Free",
yearly: "Free",
features: [
"Schema & Data exploration",
"Database design with AML",
"Unlimited Tables",
"2 projects with 2 layouts of 10 tables",
"2 collaborators"
],
cta: "Select this plan",
buy: "/login?plan=free",
selected: false
"Unlimited tables",
"Schema exploration",
"Data exploration"
]
},
%{
id: :pro,
name: "Pro",
description: "Remove limits, make Azimutt a central space for collaboration.",
monthly: 13,
annually: 130,
solo: %{
id: :solo,
name: "Solo",
description: "Personal usage with one project. Allows design and custom colors.",
monthly: 9,
yearly: 7,
unit: "€ / month",
features: [
"Everything included in Explorer",
"Unlimited projects",
"Unlimited layouts",
"Unlimited notes & memos",
"Full database analysis",
"Premium support"
],
cta: "Try this plan",
buy: "/login?plan=pro",
selected: true
"Free plan features",
"Long term usage",
"Database design",
"Schema export"
]
},
%{
team: %{
id: :team,
name: "Team",
description: "Collaborate on Azimutt with all database features.",
monthly: 42,
yearly: 35,
unit: "€ / user / month",
features: [
"Solo plan features",
"Database analysis",
"Collaboration",
"Documentation",
"AI capabilities",
"Export project"
]
},
enterprise: %{
id: :enterprise,
name: "Enterprise",
description: "Features you only dreamed of to ease database understanding and management.",
monthly: nil,
annually: nil,
description: "Getting serious: higher limits, security, control and automation.",
monthly: "Custom",
yearly: "Custom",
features: [
"Everything included in Pro",
"User roles",
"Schema change alerting",
"Advanced data access",
"AI query generation"
],
cta: "Contact us",
buy: "mailto:#{Azimutt.config(:support_email)}",
selected: false
"Team plan features",
"Unlimited usage",
"User management",
"Custom integrations"
]
},
pro: %{
id: :pro,
name: "Pro",
monthly: 13,
yearly: 13,
features: []
}
]
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

Incomplete Integration of New Plan Attributes and Features

The new plan attributes and features (:free, :solo, :team, :enterprise, :pro) are only referenced in backend/lib/azimutt.ex and backend/lib/azimutt_web/controllers/user_onboarding_controller.ex. Ensure these attributes and features are correctly integrated and utilized throughout the codebase.

  • backend/lib/azimutt.ex
  • backend/lib/azimutt_web/controllers/user_onboarding_controller.ex
Analysis chain

LGTM!

The new plan attributes and features align with the updated pricing plans. Ensure that these attributes and features are correctly integrated and used throughout the codebase.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the integration of new plan attributes and features.

# Test: Search for the usage of the new attributes and features. Expect: Correct integration and usage.
rg --type elixir 'id: :free|id: :solo|id: :team|id: :enterprise|id: :pro'

Length of output: 406



Script:

#!/bin/bash
# Description: Verify the integration of new plan attributes and features across the entire codebase.

# Test: Search for the usage of the new attributes and features. Expect: Correct integration and usage.
rg --type elixir 'name: "Free"|name: "Solo"|name: "Team"|name: "Enterprise"|name: "Pro"|description: "Quickly explore your db with one command. No long term save."|description: "Personal usage with one project. Allows design and custom colors."|description: "Collaborate on Azimutt with all database features."|description: "Getting serious: higher limits, security, control and automation."|monthly: 9|monthly: 42|monthly: 13|monthly: "Custom"|yearly: 7|yearly: 35|yearly: 13|yearly: "Custom"|features: \["Unlimited tables"|features: \["Free plan features"|features: \["Solo plan features"|features: \["Team plan features"'

Length of output: 1646



Script:

#!/bin/bash
# Description: Verify the usage of new plan keys across the entire codebase.

# Test: Search for the usage of the new plan keys. Expect: Correct integration and usage.
rg --type elixir ':free|:solo|:team|:enterprise|:pro'

Length of output: 10558

Comment on lines 287 to 297
def get_organization_plan(%Organization{} = organization, maybe_current_user) do
plans = Azimutt.config(:instance_plans) || ["free"]

defp heroku_plan(plans, %Heroku.Resource{} = resource) do
if (resource.plan |> String.starts_with?("pro-") || resource.plan == "test") && plans |> Enum.member?("pro") do
{:ok, OrganizationPlan.pro()}
if organization.plan == nil || Date.compare(organization.plan_validated, Timex.shift(DateTime.utc_now(), days: -1)) == :lt do
validate_organization_plan(organization)
else
{:ok, OrganizationPlan.free()}
{:ok, organization.plan}
end
end

defp stripe_plan(plans, subscription_id) do
StripeSrv.get_subscription(subscription_id)
|> Result.map(fn s ->
if (s.status == "trialing" || s.status == "active" || s.status == "past_due" || s.status == "unpaid") && plans |> Enum.member?("pro") do
OrganizationPlan.pro()
else
OrganizationPlan.free()
end
|> Result.map(fn plan ->
plan_id = String.to_atom(if(plans |> Enum.member?(plan), do: plan, else: "free"))

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve readability by breaking down nested conditionals and transformations.

The nested conditionals and transformations make the function harder to read. Consider breaking them down for better readability.

def get_organization_plan(%Organization{} = organization, maybe_current_user) do
  plans = Azimutt.config(:instance_plans) || ["free"]

  validated_plan = 
    if organization.plan == nil || Date.compare(organization.plan_validated, Timex.shift(DateTime.utc_now(), days: -1)) == :lt do
      validate_organization_plan(organization)
    else
      {:ok, organization.plan}
    end

  validated_plan
  |> Result.map(fn plan ->
    plan_id = String.to_atom(if plans |> Enum.member?(plan), do: plan, else: "free")
    build_organization_plan(plan_id)
  end)
  |> Result.map(fn plan -> plan_overrides(plans, organization, plan, maybe_current_user) end)
end

defp build_organization_plan(plan_id) do
  %OrganizationPlan{
    id: Azimutt.plans()[plan_id].id,
    name: Azimutt.plans()[plan_id].name,
    data_exploration: Azimutt.limits().data_exploration[plan_id],
    colors: Azimutt.limits().colors[plan_id],
    aml: Azimutt.limits().aml[plan_id],
    schema_export: Azimutt.limits().schema_export[plan_id],
    ai: Azimutt.limits().ai[plan_id],
    analysis: Azimutt.limits().analysis[plan_id],
    project_export: Azimutt.limits().project_export[plan_id],
    projects: Azimutt.limits().projects[plan_id],
    project_dbs: Azimutt.limits().project_dbs[plan_id],
    project_layouts: Azimutt.limits().project_layouts[plan_id],
    layout_tables: Azimutt.limits().layout_tables[plan_id],
    project_doc: Azimutt.limits().project_doc[plan_id],
    project_share: Azimutt.limits().project_share[plan_id],
    streak: 0
  }
end

Comment on lines 320 to 328
defp plan_overrides(plans, %Organization{} = organization, %OrganizationPlan{} = plan, maybe_current_user) do
if organization.data != nil && plans |> Enum.member?("pro") do
plan
|> override_projects(organization.data)
|> override_layouts(organization.data)
|> override_layout_tables(organization.data)
|> override_memos(organization.data)
|> override_colors(organization.data)
|> override_local_save(organization.data)
|> override_private_links(organization.data)
|> override_analysis(organization.data)
|> override_int(organization.data, :projects, :allowed_projects)
|> override_int(organization.data, :project_layouts, :allowed_layouts)
|> override_int(organization.data, :layout_tables, :allowed_layout_tables)
|> override_bool(organization.data, :colors, :allow_table_color)
|> override_bool(organization.data, :project_share, :allow_private_links)
|> override_bool(organization.data, :db_analysis, :allow_database_analysis)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve readability by breaking down nested transformations.

The nested transformations make the function harder to read. Consider breaking them down for better readability.

defp plan_overrides(plans, %Organization{} = organization, %OrganizationPlan{} = plan, maybe_current_user) do
  plan
  |> apply_plan_overrides(organization, plans)
  |> override_streak(maybe_current_user)
end

defp apply_plan_overrides(plan, organization, plans) do
  if organization.data != nil && plans |> Enum.member?("pro") do
    plan
    |> override_int(organization.data, :projects, :allowed_projects)
    |> override_int(organization.data, :project_layouts, :allowed_layouts)
    |> override_int(organization.data, :layout_tables, :allowed_layout_tables)
    |> override_bool(organization.data, :colors, :allow_table_color)
    |> override_bool(organization.data, :project_share, :allow_private_links)
    |> override_bool(organization.data, :db_analysis, :allow_database_analysis)
  else
    plan
  end
end

Comment on lines 341 to 352
defp override_streak(%OrganizationPlan{} = plan, %User{} = maybe_current_user) do
# MUST stay sync with backend/lib/azimutt_web/templates/partials/_streak.html.heex
streak = Tracking.get_streak(maybe_current_user) |> Result.or_else(0)
plan = %{plan | streak: streak}
plan = if(streak >= 4, do: %{plan | colors: true}, else: plan)
plan = if(streak >= 6, do: %{plan | project_doc: nil}, else: plan)
plan = if(streak >= 10, do: %{plan | project_layouts: nil}, else: plan)
plan = if(streak >= 15, do: %{plan | project_doc: nil}, else: plan)
plan = if(streak >= 25, do: %{plan | schema_export: true}, else: plan)
plan = if(streak >= 40, do: %{plan | analysis: true}, else: plan)
plan = if(streak >= 60, do: %{plan | project_share: true}, else: plan)
plan
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve readability by breaking down conditional checks.

The multiple conditional checks make the function harder to read. Consider breaking them down for better readability.

defp override_streak(%OrganizationPlan{} = plan, %User{} = maybe_current_user) do
  streak = Tracking.get_streak(maybe_current_user) |> Result.or_else(0)
  plan
  |> Map.put(:streak, streak)
  |> apply_streak_overrides(streak)
end

defp apply_streak_overrides(plan, streak) do
  plan
  |> maybe_override(streak >= 4, :colors, true)
  |> maybe_override(streak >= 6, :project_doc, nil)
  |> maybe_override(streak >= 10, :project_layouts, nil)
  |> maybe_override(streak >= 15, :project_doc, nil)
  |> maybe_override(streak >= 25, :schema_export, true)
  |> maybe_override(streak >= 40, :analysis, true)
  |> maybe_override(streak >= 60, :project_share, true)
end

defp maybe_override(plan, condition, key, value) do
  if condition, do: Map.put(plan, key, value), else: plan
end

backend/lib/azimutt/organizations.ex Outdated Show resolved Hide resolved
backend/lib/azimutt/organizations.ex Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 24d0768 and aeb74d6.

Files selected for processing (31)
  • backend/lib/azimutt.ex (1 hunks)
  • frontend/src/Components/Book.elm (4 hunks)
  • frontend/src/Components/Slices/ExportDialogBody.elm (11 hunks)
  • frontend/src/Components/Slices/NewLayoutBody.elm (4 hunks)
  • frontend/src/Components/Slices/PlanDialog.elm (21 hunks)
  • frontend/src/Components/Slices/ProjectSaveDialogBody.elm (6 hunks)
  • frontend/src/Models/Feature.elm (1 hunks)
  • frontend/src/Models/Organization.elm (3 hunks)
  • frontend/src/Models/ProjectRef.elm (1 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Components/ExportDialog.elm (3 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Components/ProjectSharing.elm (11 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Models.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Models/Erd.elm (4 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Updates.elm (11 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Updates/Groups.elm (6 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Updates/Memo.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/NewLayout.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis.elm (3 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnColumns.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnRelations.elm (4 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/IndexDuplicated.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/IndexOnForeignKeys.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/NamingConsistency.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/PrimaryKeyMissing.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/RelationMissing.elm (5 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableTooBig.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableWithoutIndex.elm (2 hunks)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Navbar/Title.elm (4 hunks)
  • frontend/src/Services/Backend.elm (1 hunks)
  • package.json (1 hunks)
Files skipped from review due to trivial changes (2)
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/PrimaryKeyMissing.elm
  • package.json
Files skipped from review as they are similar to previous changes (13)
  • frontend/src/Components/Slices/ExportDialogBody.elm
  • frontend/src/Components/Slices/NewLayoutBody.elm
  • frontend/src/Components/Slices/ProjectSaveDialogBody.elm
  • frontend/src/Models/Feature.elm
  • frontend/src/PagesComponents/Organization_/Project_/Components/ProjectSharing.elm
  • frontend/src/PagesComponents/Organization_/Project_/Models/Erd.elm
  • frontend/src/PagesComponents/Organization_/Project_/Updates.elm
  • frontend/src/PagesComponents/Organization_/Project_/Updates/Groups.elm
  • frontend/src/PagesComponents/Organization_/Project_/Updates/Memo.elm
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/NewLayout.elm
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis.elm
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnRelations.elm
  • frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/RelationMissing.elm
Additional comments not posted (57)
frontend/src/Models/ProjectRef.elm (3)

13-13: LGTM!

The zero function now initializes ProjectRef with Just values for id and organization.


18-18: LGTM!

The one function now initializes ProjectRef with Just values for id and organization.


8-8: Ensure consistency with Maybe types for ProjectRef.

The ProjectRef type alias now uses Maybe for id and organization. Verify that other parts of the codebase handle these Maybe types correctly.

Verification successful

Ensure Maybe type handling for ProjectRef.

The ProjectRef type alias now uses Maybe for id and organization. Verify that other parts of the codebase handle these Maybe types correctly.


Ensure Maybe type handling for ProjectRef.

The ProjectRef type alias now uses Maybe for id and organization. The provided code snippets show that these fields are accessed and utilized in multiple places. Here are some key points confirming the correct handling of Maybe types:

  • frontend/src/PagesComponents/Organization_/Project_/Models/Erd.elm:

    getProjectRef : UrlInfos -> List Organization -> Maybe Erd -> ProjectRef
    getProjectRef urlInfos organizations erd =
        { id = erd |> Maybe.map (.project >> .id) |> Maybe.orElse urlInfos.project
        , organization = erd |> Maybe.andThen (.project >> .organization) |> Maybe.orElse (urlInfos.organization |> Maybe.andThen (\id -> organizations |> List.findBy .id id))
        }

    This function uses Maybe.map and Maybe.orElse to handle Maybe types correctly.

  • frontend/src/Components/Slices/PlanDialog.elm:

    projectsModalBody : ProjectRef -> msg -> HtmlId -> Html msg
    projectsModalBody project close titleId =
        let
            ( color, limit ) =
                ( Tw.teal, project.organization |> Maybe.andThen (.plan >> .projects) |> Maybe.withDefault Feature.projects.default )
        in

    The organization field is accessed using Maybe.andThen and Maybe.withDefault, ensuring proper handling of Nothing.

These examples demonstrate that the Maybe types are being handled correctly in the codebase.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify usage of `ProjectRef` to ensure consistency with `Maybe` types.

# Test: Search for the usage of `ProjectRef`. Expect: Proper handling of `Maybe` types.
rg --type elm $'ProjectRef'

Length of output: 13873



Script:

#!/bin/bash
# Extract relevant code snippets where ProjectRef is used to verify handling of Maybe types.

# Files where ProjectRef is used
files=(
  "frontend/src/PagesComponents/Organization_/Project_/Updates.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Components/ExportDialog.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Components/ProjectSharing.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Updates/Groups.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Models/Erd.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/NewLayout.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/IndexDuplicated.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnColumns.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnRelations.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableWithoutIndex.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableTooBig.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/RelationMissing.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/IndexOnForeignKeys.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/NamingConsistency.elm"
  "frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/PrimaryKeyMissing.elm"
  "frontend/src/Components/Slices/PlanDialog.elm"
  "frontend/src/Components/Slices/NewLayoutBody.elm"
  "frontend/src/Components/Slices/ExportDialogBody.elm"
)

# Extract code snippets showing usage of ProjectRef
for file in "${files[@]}"; do
  echo "File: $file"
  rg --context 5 "ProjectRef" "$file"
  echo -e "\n\n"
done

Length of output: 41977

frontend/src/PagesComponents/Organization_/Project_/Components/ExportDialog.elm (1)

Line range hint 34-44: Ensure correct handling of BodyMsg in update function.

The update function handles different messages, including BodyMsg. Verify that the BodyMsg message is correctly processed and the model is updated accordingly.

Verification successful

Ensure correct handling of BodyMsg in update function.

The update function in ExportDialogBody.elm correctly processes various messages, including SetInput, SetFormat, GetOutput, and GotOutput. The logic for handling these messages and updating the model appears sound.

  • The update function updates the model appropriately based on the message received.
  • The shouldGetOutput function ensures that the output is fetched only if it is not already being fetched.
  • The getOutput function handles different export formats and fetches the output accordingly.

The handling of BodyMsg in the update function of ExportDialog.elm is correct and the model is updated as expected.

Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify handling of `BodyMsg` in `update` function.

# Test: Search for the usage of `BodyMsg` in the codebase. Expect: Correct processing and model update.
rg --type elm $'BodyMsg'

Length of output: 2428



Script:

#!/bin/bash
# Description: Verify handling of `BodyMsg` in `ExportDialogBody.update` function.

# Locate the definition of `ExportDialogBody.update` and check its implementation.
ast-grep --lang elm --pattern $'update($_, $_, $_, $_) {' --search frontend/src/PagesComponents/Organization_/Project_/Components/ExportDialogBody.elm

Length of output: 258



Script:

#!/bin/bash
# Description: Verify handling of `BodyMsg` in `ExportDialogBody.update` function.

# Locate the definition of `update` in ExportDialogBody.elm and check its implementation.
rg 'update' frontend/src/PagesComponents/Organization_/Project_/Components/ExportDialogBody.elm

Length of output: 219



Script:

#!/bin/bash
# Description: Locate the file containing `ExportDialogBody` and verify the `update` function.

# Locate the file containing `ExportDialogBody`.
fd ExportDialogBody

# Once located, search for the `update` function within the identified file.
fd ExportDialogBody -x rg 'update' {}

Length of output: 1051



Script:

#!/bin/bash
# Description: Retrieve the full implementation of the `update` function from `ExportDialogBody.elm`.

# Extract the full `update` function implementation for inspection.
sed -n '/update : (Msg -> msg) -> ProjectRef -> Erd -> Msg -> Model -> ( Model, Extra msg )/,/^}/p' frontend/src/Components/Slices/ExportDialogBody.elm

Length of output: 11358

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableWithoutIndex.elm (1)

4-4: Verify usage of PlanDialog module.

The PlanDialog module has been imported. Ensure that this module is used correctly in the file and the import is necessary.

Verification successful

Import of PlanDialog module is necessary.

The PlanDialog module is used in the file with PlanDialog.analysisResults project, confirming that the import is required and correctly utilized.

  • Line 4: import Components.Slices.PlanDialog as PlanDialog
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify usage of `PlanDialog` module in the file.

# Test: Search for the usage of `PlanDialog` in the file. Expect: Correct usage and necessity of import.
rg --type elm $'PlanDialog' frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableWithoutIndex.elm

Length of output: 223

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/TableTooBig.elm (2)

4-4: Import Approved.

The import of PlanDialog is necessary for the changes made in the view function.


Line range hint 56-61: Change Approved.

The use of PlanDialog.analysisResults in the view function enhances the display of analysis results.

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/NamingConsistency.elm (2)

3-3: Import Approved.

The import of PlanDialog is necessary for the changes made in the view function.


77-77: Change Approved.

The use of PlanDialog.analysisResults in the view function enhances the display of analysis results.

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/InconsistentTypeOnColumns.elm (2)

4-4: Import Approved.

The import of PlanDialog is necessary for the changes made in the view function.


Line range hint 59-69: Change Approved.

The use of PlanDialog.analysisResults in the view function enhances the display of analysis results.

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/IndexDuplicated.elm (3)

Line range hint 14-14: LGTM!


Line range hint 24-24: LGTM!


Line range hint 82-82: LGTM!

frontend/src/PagesComponents/Organization_/Project_/Views/Modals/SchemaAnalysis/IndexOnForeignKeys.elm (4)

Line range hint 14-14: LGTM!


Line range hint 53-53: LGTM!


Line range hint 82-82: LGTM!


89-89: LGTM!

Ensure that PlanDialog.analysisResults is correctly implemented and tested.

Verification successful

LGTM!

The PlanDialog.analysisResults function is correctly implemented.

  • frontend/src/Components/Slices/PlanDialog.elm:
    • analysisResults : ProjectRef -> List a -> (a -> Html msg) -> Html msg
    • The function conditionally renders analysis results based on project capabilities and item limits.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify the implementation of `PlanDialog.analysisResults`.

# Test: Search for the function implementation. Expect: Only one occurrence.
rg --type elm $'PlanDialog.analysisResults'

Length of output: 1633



Script:

#!/bin/bash
# Description: Locate the implementation of `PlanDialog.analysisResults`.

# Search for the definition of `analysisResults` within the `PlanDialog` module.
rg --type elm 'analysisResults' | grep 'PlanDialog'

Length of output: 2384



Script:

#!/bin/bash
# Description: Retrieve the implementation of `analysisResults` in `PlanDialog`.

# Extract the implementation of `analysisResults` from the PlanDialog module.
ast-grep --lang elm --pattern $'analysisResults : ProjectRef -> List a -> (a -> Html msg) -> Html msg\nanalysisResults project items render =\n    $$$' frontend/src/Components/Slices/PlanDialog.elm

Length of output: 303



Script:

#!/bin/bash
# Description: Retrieve the implementation of `analysisResults` in `PlanDialog` using `rg`.

# Extract lines around the definition of `analysisResults` in `PlanDialog.elm`.
rg --type elm -A 10 -B 2 'analysisResults project items render =' frontend/src/Components/Slices/PlanDialog.elm

Length of output: 495



Script:

#!/bin/bash
# Description: Retrieve the complete implementation of `analysisResults` in `PlanDialog` using `rg`.

# Extract more lines around the definition of `analysisResults` in `PlanDialog.elm`.
rg --type elm -A 20 -B 2 'analysisResults project items render =' frontend/src/Components/Slices/PlanDialog.elm

Length of output: 1222

frontend/src/Models/Organization.elm (8)

29-31: LGTM!


34-36: LGTM!


39-41: LGTM!


44-46: LGTM!


49-51: LGTM!


54-56: LGTM!


59-61: LGTM!


64-66: LGTM!

frontend/src/Components/Book.elm (3)

46-46: New Import: PlanDialog

The PlanDialog component has been imported. Ensure it is used correctly within the file.


74-74: New State: planDialogDocState

The planDialogDocState has been added to the DocState type alias. Ensure it is initialized and used appropriately.


102-102: Initialize planDialogDocState

The planDialogDocState is initialized in the init function. Ensure the initialization is correct and consistent with the rest of the state.

backend/lib/azimutt.ex (3)

31-94: Plan Definitions Updated

The plans function has been updated to include new plans (Solo, Team, Enterprise) with revised attributes and features. Ensure these changes are consistent with the new pricing model.


97-97: New Function: active_plans

The active_plans function has been added, returning a list of active plans. Ensure this function is used correctly throughout the codebase.


99-140: Limits Definitions Updated

The limits function has been updated to reflect new plan details and extended integration features. Ensure these changes are consistent with the new pricing model and integrated correctly.

frontend/src/Services/Backend.elm (1)

82-84: New Function: organizationBillingUrl

The organizationBillingUrl function has been added to generate the billing URL for an organization. Ensure this function is used correctly and the URL is constructed accurately.

frontend/src/PagesComponents/Organization_/Project_/Views/Navbar/Title.elm (6)

28-28: Import Organization module

The import statement for Models.Organization was added. Ensure that the Organization module is used appropriately within the file.


90-91: Organize projects by organization

The projectsByOrganization variable groups projects by their organization ID. This is a useful addition for organizing projects efficiently.


100-100: Retrieve current organization projects

The currentOrganizationProjects variable retrieves projects for the current organization. This improves the code's clarity and maintainability.


104-104: Organize projects by other organizations

The organizationProjects variable organizes projects by other organizations. This improves the code's structure and readability.


107-107: Filter and map organization projects

The code filters and maps the projects to include organization details, ensuring only valid projects are included. This is a good practice for data integrity.


138-138: Add back to dashboard link

The code adds a context menu link for navigating back to the dashboard. This enhances user navigation.

frontend/src/PagesComponents/Organization_/Project_/Models.elm (2)

7-7: Import PlanDialog module

The import statement for Components.Slices.PlanDialog was added. Ensure that the PlanDialog module is used appropriately within the file.


306-306: Add new message type

The new message PlanDialogColors was added to the Msg type to handle messages from the PlanDialog module. This is a good practice for modularity.

frontend/src/PagesComponents/Organization_/Project_/Views.elm (6)

185-185: Update viewModal function

The viewModal function was updated. Ensure that the changes align with the intended functionality.


187-189: Retrieve project reference

The projectRef variable retrieves the project reference from the erd model. This improves the code's clarity and maintainability.


200-200: Map newLayout model to view function

The code maps the newLayout model to the NewLayout.view function, ensuring the new layout modal is displayed correctly.


204-204: Map schemaAnalysis model to view function

The code maps the schemaAnalysis model to the viewSchemaAnalysis function, ensuring the schema analysis modal is displayed correctly.


205-205: Map exportDialog model to view function

The code maps the exportDialog model to the ExportDialog.view function, ensuring the export dialog is displayed correctly.


206-207: Map sharing and save models to view functions

The code maps the sharing model to the ProjectSharing.view function and the save model to the ProjectSaveDialog.view function, ensuring the sharing and save dialogs are displayed correctly.

frontend/src/Components/Slices/PlanDialog.elm (10)

23-24: LGTM!

The new imports for Feature and Organization are necessary for the new plan features.


38-39: LGTM!

The updates to the draftProjectWarning and draftProjectModalBody functions align with the new paid plans.

Also applies to: 50-51


61-61: LGTM!

The updates to the projectsModalBody function correctly use the new Feature.projects.default value.

Also applies to: 68-68, 70-70


88-88: LGTM!

The updates to the layoutsWarning and layoutsModalBody functions align with the new paid plans.

Also applies to: 104-104


113-113: LGTM!

The updates to the layoutTablesModalBody function correctly use the new Feature.layoutTables.default value.

Also applies to: 120-120, 122-122


134-134: LGTM!

The updates to the ColorsMsg type and colorsUpdate function are necessary for the new plan features.

Also applies to: 158-158, 163-163


192-192: LGTM!

The updates to the colorsModalBody function align with the new paid plans.

Also applies to: 201-201, 212-212


292-294: LGTM!

The updates to the privateLinkWarning and sqlExportWarning functions align with the new paid plans.

Also applies to: 307-308, 311-311


322-322: LGTM!

The updates to the analysisWarning and analysisResults functions align with the new paid plans.

Also applies to: 328-328, 337-337, 351-351, 354-354


402-402: LGTM!

The updates to the isDraft, SharedDocState, DocState, doc, and related functions align with the new paid plans and handle the updated state correctly.

Also applies to: 410-410, 430-430, 433-434, 440-440, 444-453

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between aeb74d6 and c283895.

Files selected for processing (5)
  • backend/lib/azimutt.ex (1 hunks)
  • backend/lib/azimutt/organizations.ex (5 hunks)
  • backend/lib/azimutt/services/cockpit_srv.ex (6 hunks)
  • backend/lib/azimutt/stripe_handler.ex (3 hunks)
  • backend/lib/azimutt_web/templates/partials/_streak.html.heex (2 hunks)
Files skipped from review as they are similar to previous changes (1)
  • backend/lib/azimutt/services/cockpit_srv.ex
Additional comments not posted (13)
backend/lib/azimutt_web/templates/partials/_streak.html.heex (1)

19-25: Verify the correctness of streak rewards and descriptions.

Ensure that the rewards and descriptions for each streak milestone correctly reflect the new features and plan-related changes. This is crucial for maintaining consistency between the frontend and the backend.

backend/lib/azimutt.ex (6)

31-94: Verify the correctness of plan attributes and features.

Ensure that the attributes and features for each subscription plan are correctly defined and integrated. This is crucial for maintaining consistency across the application.


97-97: Verify the correctness of active plans.

Ensure that the list of active plans is correctly defined. This is crucial for maintaining consistency across the application.


100-140: Verify the correctness of feature limits and quotas.

Ensure that the limits for various features and quotas are correctly defined and integrated. This is crucial for maintaining consistency across the application.


143-152: Verify the correctness of streak rewards.

Ensure that the streak rewards are correctly defined and integrated. This is crucial for maintaining consistency across the application.


Line range hint 154-173: Verify the correctness of use cases.

Ensure that the use cases are correctly defined and integrated. This is crucial for maintaining consistency across the application.


Line range hint 175-254: Verify the correctness of features.

Ensure that the features are correctly defined and integrated. This is crucial for maintaining consistency across the application.

backend/lib/azimutt/organizations.ex (6)

43-44: LGTM!

The added preloads for clever_cloud_resource and heroku_resource are appropriate for eager loading related resources.


272-274: LGTM!

The function correctly retrieves and maps subscriptions from Stripe.


283-284: LGTM!

The function correctly updates the organization with a free trial.


287-318: Improve readability by breaking down nested transformations and conditionals.

The nested transformations and conditionals make the function harder to read. Consider breaking them down for better readability.

def get_organization_plan(%Organization{} = organization, maybe_current_user) do
  plans = Azimutt.config(:instance_plans) || ["free"]

  validated_plan = 
    if organization.plan == nil || Date.compare(organization.plan_validated, Timex.shift(DateTime.utc_now(), days: -1)) == :lt do
      validate_organization_plan(organization)
    else
      {:ok, organization.plan}
    end

  validated_plan
  |> Result.map(fn plan ->
    plan_id = String.to_atom(if plans |> Enum.member?(plan), do: plan, else: "free")
    build_organization_plan(plan_id)
  end)
  |> Result.map(&organization_overrides(organization, &1))
  |> Result.map(&streak_overrides(maybe_current_user, &1))
end

defp build_organization_plan(plan_id) do
  %OrganizationPlan{
    id: Azimutt.plans()[plan_id].id,
    name: Azimutt.plans()[plan_id].name,
    data_exploration: Azimutt.limits().data_exploration[plan_id],
    colors: Azimutt.limits().colors[plan_id],
    aml: Azimutt.limits().aml[plan_id],
    schema_export: Azimutt.limits().schema_export[plan_id],
    ai: Azimutt.limits().ai[plan_id],
    analysis: Azimutt.limits().analysis[plan_id],
    project_export: Azimutt.limits().project_export[plan_id],
    projects: Azimutt.limits().projects[plan_id],
    project_dbs: Azimutt.limits().project_dbs[plan_id],
    project_layouts: Azimutt.limits().project_layouts[plan_id],
    layout_tables: Azimutt.limits().layout_tables[plan_id],
    project_doc: Azimutt.limits().project_doc[plan_id],
    project_share: Azimutt.limits().project_share[plan_id],
    streak: 0
  }
end

321-329: Improve readability by breaking down nested conditionals.

The nested conditionals make the function harder to read. Consider breaking them down for better readability.

defp organization_overrides(%Organization{} = organization, %OrganizationPlan{} = plan) do
  plan
  |> apply_plan_overrides(organization)
end

defp apply_plan_overrides(plan, organization) do
  if organization.data != nil && Azimutt.config(:plan_overrides) do
    plan
    |> override_int(organization.data, :projects, :allowed_projects)
    |> override_int(organization.data, :project_layouts, :allowed_layouts)
    |> override_int(organization.data, :layout_tables, :allowed_layout_tables)
    |> override_bool(organization.data, :colors, :allow_table_color)
    |> override_bool(organization.data, :project_share, :allow_private_links)
    |> override_bool(organization.data, :db_analysis, :allow_database_analysis)
  else
    plan
  end
end

356-365: Improve readability by breaking down nested conditionals.

The nested conditionals make the function harder to read. Consider breaking them down for better readability.

def validate_organization_plan(%Organization{} = organization) do
  validated_plan =
    cond do
      organization.clever_cloud_resource -> validate_clever_cloud_plan(organization.clever_cloud_resource)
      organization.heroku_resource -> validate_heroku_plan(organization.heroku_resource)
      organization.stripe_customer_id && StripeSrv.stripe_configured?() -> validate_stripe_plan(organization.stripe_customer_id)
      true -> validate_default_plan()
    end

  validated_plan
  |> Result.tap(&update_organization_plan(organization, &1))
  |> Result.map(& &1.plan)
end

defp update_organization_plan(organization, validated) do
  organization
  |> Organization.validate_plan_changeset(validated, DateTime.utc_now())
  |> Repo.update()
end

backend/lib/azimutt/stripe_handler.ex Show resolved Hide resolved
backend/lib/azimutt/stripe_handler.ex Show resolved Hide resolved
backend/lib/azimutt/stripe_handler.ex Show resolved Hide resolved
backend/lib/azimutt/stripe_handler.ex Show resolved Hide resolved
backend/lib/azimutt/stripe_handler.ex Show resolved Hide resolved
backend/lib/azimutt/stripe_handler.ex Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Outside diff range and nitpick comments (1)
INSTALL.md (1)

Line range hint 49-49: Grammar correction needed.

Consider adding a comma after "For that".

- For that you can use the `--env-file` option with a the `.env.example` file set up with your configuration.
+ For that, you can use the `--env-file` option with the `.env.example` file set up with your configuration.
Tools
LanguageTool

[uncategorized] ~131-~131: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...and others), should be at least 64 bytes and you probably want a random value for it...

(COMMA_COMPOUND_SENTENCE)

Markdownlint

134-134: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


135-135: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


132-132: null
Bare URL used

(MD034, no-bare-urls)

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c283895 and 1819d82.

Files selected for processing (9)
  • INSTALL.md (4 hunks)
  • backend/lib/azimutt.ex (1 hunks)
  • backend/lib/azimutt/clever_cloud.ex (2 hunks)
  • backend/lib/azimutt/heroku.ex (2 hunks)
  • backend/lib/azimutt/organizations.ex (5 hunks)
  • backend/lib/azimutt/organizations/organization/data.ex (1 hunks)
  • backend/lib/azimutt/organizations/organization_plan.ex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/billing.html.heex (1 hunks)
  • backend/lib/azimutt_web/templates/organization/subscribe.html.heex (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • backend/lib/azimutt/clever_cloud.ex
  • backend/lib/azimutt/heroku.ex
  • backend/lib/azimutt/organizations/organization/data.ex
Additional context used
LanguageTool
INSTALL.md

[uncategorized] ~9-~9: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...age](#build-your-own-docker-image) - Bare metal installation...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~27-~27: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...image](#build-your-own-docker-image) - Bare metal installation...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[typographical] ~49-~49: Consider adding a comma here.
Context: ...and give them to your Docker container. For that you can use the --env-file option wit...

(FOR_THAT_COMMA)


[grammar] ~49-~49: Two determiners in a row. Choose either “a” or “the”.
Context: ...ou can use the --env-file option with a the .env.example file set up with your co...

(DT_DT)


[uncategorized] ~110-~110: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...nning on http://localhost:4000. ### Bare metal installation TODO But in short you wi...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[uncategorized] ~131-~131: Use a comma before ‘and’ if it connects two independent clauses (unless they are closely connected and short).
Context: ...and others), should be at least 64 bytes and you probably want a random value for it...

(COMMA_COMPOUND_SENTENCE)


[uncategorized] ~160-~160: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...imutt.app`): email shown in Azimutt for high priority support ### Key features At least on...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[typographical] ~160-~160: Except for inverted sentences, ‘will us’ requires a question mark at the end of the sentence.
Context: ...mail shown in Azimutt for high priority support ### Key features At least one of aut...

(MD_PRP_QUESTION_MARK)


[typographical] ~178-~178: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...to use Azimutt until they confirm their email, otherwise they will have a soft confirmation bann...

(THUS_SENTENCE)


[grammar] ~182-~182: Did you mean “working”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...he global organization is shown (allows to work like a mono-tenant app) - RECAPTCHA (...

(ALLOW_TO)


[grammar] ~190-~190: Did you mean “using”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ... TWITTER (optional): if true, allow to use Twitter API to fetch tweets & unlock fe...

(ALLOW_TO)


[typographical] ~199-~199: The word “otherwise” is an adverb that can’t be used like a conjunction, and therefore needs to be separated from the sentence.
Context: ...ional): if true, will show the public site, otherwise home will redirect to login page (you p...

(THUS_SENTENCE)


[style] ~199-~199: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...e home will redirect to login page (you probably don't want it) - GITHUB (optional): i...

(REP_PROBABLY)


[grammar] ~200-~200: Did you mean “using”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...- GITHUB (optional): if true, allow to use GitHub API, no real usage for now -...

(ALLOW_TO)


[grammar] ~209-~209: Did you mean “purchasing”? Or maybe you should add a pronoun? In active voice, ‘allow’ + ‘to’ takes an object, usually a pronoun.
Context: ...- STRIPE (optional): if true, allow to purchase plans with Stripe...

(ALLOW_TO)

Markdownlint
INSTALL.md

134-134: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


135-135: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


136-136: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


138-138: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


139-139: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


140-140: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


141-141: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


142-142: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


143-143: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


144-144: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


146-146: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


147-147: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


148-148: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


149-149: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


150-150: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


151-151: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


152-152: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


153-153: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


154-154: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


155-155: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


156-156: Expected: 4; Actual: 8
Unordered list indentation

(MD007, ul-indent)


169-169: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


170-170: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


182-182: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


184-184: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


185-185: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


186-186: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


188-188: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


189-189: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


191-191: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


192-192: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


193-193: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


194-194: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


201-201: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


203-203: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


204-204: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


206-206: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


207-207: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


208-208: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


210-210: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


211-211: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


212-212: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


213-213: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


214-214: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


215-215: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


216-216: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


217-217: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


219-219: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


220-220: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


221-221: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


223-223: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


224-224: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


225-225: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


227-227: Expected: 2; Actual: 4
Unordered list indentation

(MD007, ul-indent)


12-12: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


22-22: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


29-29: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


36-36: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


45-45: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


60-60: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


67-67: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


76-76: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


87-87: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


94-94: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


109-109: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


117-117: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


122-122: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


162-162: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


172-172: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


196-196: Expected: 1; Actual: 2
Multiple consecutive blank lines

(MD012, no-multiple-blanks)


132-132: null
Bare URL used

(MD034, no-bare-urls)

Gitleaks
INSTALL.md

210-210: Found a Stripe Access Token, posing a risk to payment processing services and sensitive financial data.

(stripe-access-token)

Additional comments not posted (27)
backend/lib/azimutt/organizations/organization_plan.ex (4)

19-20: Ensure field types match expected data.

Verify that the new field project_dbs is correctly typed as integer() | nil and the modified field project_layouts is correctly typed.

Verification successful

Field types are correctly defined.

The fields project_dbs and project_layouts in backend/lib/azimutt/organizations/organization_plan.ex are correctly typed as integer() | nil.

  • field :project_dbs, integer() | nil
  • field :project_layouts, integer() | nil
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify field types in OrganizationPlan.

# Test: Ensure that field types match expected data types.
rg --type elixir $'field :project_dbs, integer() | nil' && \
rg --type elixir $'field :project_layouts, integer() | nil'

Length of output: 41981


11-16: Ensure field types match expected data.

Verify that the new fields data_exploration, colors, aml, schema_export, and ai are correctly typed as booleans and analysis as a string.

Verification successful

Field types are correctly defined.

The fields data_exploration, colors, aml, schema_export, and ai are correctly typed as booleans, and analysis is correctly typed as a string in the organization_plan.ex file.

  • data_exploration: boolean
  • colors: boolean
  • aml: boolean
  • schema_export: boolean
  • ai: boolean
  • analysis: String.t()
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify field types in OrganizationPlan.

# Test: Ensure that field types match expected data types.
rg --type elixir $'field :data_exploration, boolean()' && \
rg --type elixir $'field :colors, boolean()' && \
rg --type elixir $'field :aml, boolean()' && \
rg --type elixir $'field :schema_export, boolean()' && \
rg --type elixir $'field :ai, boolean()' && \
rg --type elixir $'field :analysis, String.t()'

Length of output: 805


22-23: Ensure field types match expected data.

Verify that the new fields project_doc and project_share are correctly typed as integer() | nil and boolean() respectively.

Verification successful

Field types are correctly defined.

The project_doc field is correctly typed as integer() | nil and the project_share field is correctly typed as boolean().

  • backend/lib/azimutt/organizations/organization_plan.ex
    • Line 22: field :project_doc, integer() | nil
    • Line 23: field :project_share, boolean()
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify field types in OrganizationPlan.

# Test: Ensure that field types match expected data types.
rg --type elixir $'field :project_doc, integer() | nil' && \
rg --type elixir $'field :project_share, boolean()'

Length of output: 21132



Script:

#!/bin/bash
# Description: Verify field type for project_doc in OrganizationPlan.

# Test: Ensure that field type for project_doc is defined correctly.
rg --type elixir 'field :project_doc' backend/lib/azimutt/organizations/organization_plan.ex

Length of output: 134


27-43: Ensure correct initialization of new fields.

Verify that the build function correctly initializes all new fields (data_exploration, colors, aml, schema_export, ai, analysis, project_export, project_dbs, project_layouts, project_doc, and project_share).

Verification successful

Correct initialization of new fields verified.

The build function correctly initializes all the new fields (data_exploration, colors, aml, schema_export, ai, analysis, project_export, project_dbs, project_layouts, project_doc, and project_share).

  • data_exploration: Azimutt.limits().data_exploration[plan]
  • colors: Azimutt.limits().colors[plan]
  • aml: Azimutt.limits().aml[plan]
  • schema_export: Azimutt.limits().schema_export[plan]
  • ai: Azimutt.limits().ai[plan]
  • analysis: Azimutt.limits().analysis[plan]
  • project_export: Azimutt.limits().project_export[plan]
  • project_dbs: Azimutt.limits().project_dbs[plan]
  • project_layouts: Azimutt.limits().project_layouts[plan]
  • project_doc: Azimutt.limits().project_doc[plan]
  • project_share: Azimutt.limits().project_share[plan]
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify field initialization in the build function.

# Test: Ensure that all new fields are correctly initialized.
rg --type elixir $'data_exploration: Azimutt.limits().data_exploration[plan]' && \
rg --type elixir $'colors: Azimutt.limits().colors[plan]' && \
rg --type elixir $'aml: Azimutt.limits().aml[plan]' && \
rg --type elixir $'schema_export: Azimutt.limits().schema_export[plan]' && \
rg --type elixir $'ai: Azimutt.limits().ai[plan]' && \
rg --type elixir $'analysis: Azimutt.limits().analysis[plan]' && \
rg --type elixir $'project_export: Azimutt.limits().project_export[plan]' && \
rg --type elixir $'project_dbs: Azimutt.limits().project_dbs[plan]' && \
rg --type elixir $'project_layouts: Azimutt.limits().project_layouts[plan]' && \
rg --type elixir $'project_doc: Azimutt.limits().project_doc[plan]' && \
rg --type elixir $'project_share: Azimutt.limits().project_share[plan]'

Length of output: 78



Script:

#!/bin/bash
# Verify if the fields exist in the Azimutt.limits() function.

# List of fields to verify
fields=(
  "data_exploration"
  "colors"
  "aml"
  "schema_export"
  "ai"
  "analysis"
  "project_export"
  "project_dbs"
  "project_layouts"
  "project_doc"
  "project_share"
)

# Check each field in the Azimutt.limits() function
for field in "${fields[@]}"; do
  echo "Checking for field: $field"
  rg --type elixir "$field" || echo "Field $field not found."
done

Length of output: 77238

backend/lib/azimutt_web/templates/organization/subscribe.html.heex (2)

24-26: Ensure correct rendering of new plans.

Verify that the render function correctly includes the new plans (solo, team, enterprise).


7-7: Verify email link formatting.

Ensure that the email link for contacting support is correctly formatted.

Verification successful

Verified email link formatting.

The email link for contacting support is correctly formatted as mailto:#{Azimutt.config(:contact_email)} and is used consistently across the codebase.

  • backend/lib/azimutt_web/templates/organization/subscribe.html.heex
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify email link formatting.

# Test: Ensure that the email link is correctly formatted.
rg --type html $'mailto:#{Azimutt.config(:contact_email)}'

Length of output: 191



Script:

#!/bin/bash
# Description: Verify email link formatting by searching for the specific HTML line.

# Use a different approach to search for the email link formatting within HTML files.
rg --type html 'mailto:\#\{Azimutt\.config\(:contact_email\)\}'

Length of output: 65



Script:

#!/bin/bash
# Description: Verify the configuration settings for the contact email.

# Search for the contact email configuration in the codebase.
rg --type js 'Azimutt.config\(:contact_email\)'

Length of output: 49



Script:

#!/bin/bash
# Description: Search for the term "contact_email" across the entire codebase.

# Search for the term "contact_email" to identify its definition or usage.
rg 'contact_email'

Length of output: 2150

backend/lib/azimutt_web/templates/organization/billing.html.heex (4)

21-21: Verify text formatting.

Ensure that the text for managing subscription seats or plan is correctly formatted and provides clear instructions.

Verification successful

Let's refine our search to ensure we capture the intended text. We'll look for variations and broader contexts around the subscription management text.


Let's directly inspect the content of the specified file to verify the presence of the text.


Verify text formatting.

The text for managing subscription seats or plan is correctly formatted and provides clear instructions.

  • backend/lib/azimutt_web/templates/organization/billing.html.heex:
    • Line 21: Change your seats or plan using the "Manage your subscription" button.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify text formatting for subscription management.

# Test: Ensure that the text is correctly formatted.
rg --type html $'"Manage your subscription"'

Length of output: 45



Script:

#!/bin/bash
# Description: Verify text formatting for subscription management.

# Test: Search for broader context or similar phrases around subscription management.
rg --type html 'subscription' -C 2

Length of output: 34



Script:

#!/bin/bash
# Description: Inspect the content of the specified file for subscription management text.

# Test: Display the content of the file to verify the presence of the text.
cat backend/lib/azimutt_web/templates/organization/billing.html.heex

Length of output: 4927


33-34: Verify migration instructions formatting.

Ensure that the migration instructions for legacy plans are clear and correctly formatted.

Verification successful

Verified migration instructions formatting.

The migration instructions for legacy plans are clear and correctly formatted.

  • The hyperlink to the new plans is correctly formatted.
  • The instructions to cancel and resubscribe are clear.
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify migration instructions formatting.

# Test: Ensure that the migration instructions are clear and correctly formatted.
rg --type html $'Please migrate to the <a href={Routes.website_path(@conn, :pricing)} target="_blank" class="underline text-yellow-800 hover:text-yellow-900">new ones</a> as mentioned in the email.<br>'

Length of output: 501



Script:

#!/bin/bash
# Description: Verify migration instructions formatting.

# Test: Ensure that the migration instructions are clear and correctly formatted.
rg --type html $'Please migrate to the <a href=\{Routes.website_path(@conn, :pricing)\} target="_blank" class="underline text-yellow-800 hover:text-yellow-900">new ones</a> as mentioned in the email.<br>'

Length of output: 205



Script:

#!/bin/bash
# Description: Verify migration instructions formatting.

# Test: Ensure that the migration instructions are clear and correctly formatted.
rg --type html 'Please migrate to the <a href=.*>new ones</a> as mentioned in the email.<br>'

Length of output: 95



Script:

#!/bin/bash
# Description: Locate and display the relevant lines from billing.html.heex for manual inspection.

# Locate the billing.html.heex file
file_path=$(fd billing.html.heex)

# Display lines 30-35 from the located file for manual inspection
if [ -n "$file_path" ]; then
  sed -n '30,35p' "$file_path"
else
  echo "File not found."
fi

Length of output: 820


7-7: Verify email link formatting.

Ensure that the email link for enterprise support is correctly formatted.

Verification successful

Email link formatting verified.

The email link for enterprise support is correctly formatted in the file backend/lib/azimutt_web/templates/organization/billing.html.heex as expected.

  • Line 7: <a href={"mailto:#{Azimutt.config(:enterprise_support_email)}"} class="underline text-indigo-600 hover:text-indigo-900"><%= Azimutt.config(:enterprise_support_email) %></a>
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify email link formatting.

# Test: Ensure that the email link is correctly formatted.
rg --type html $'mailto:#{Azimutt.config(:enterprise_support_email)}'

Length of output: 213



Script:

#!/bin/bash
# Description: Verify email link formatting.

# Test: Ensure that the email link is correctly formatted.
rg --type html 'mailto:\#\{Azimutt.config\(:enterprise_support_email\)\}'

Length of output: 75



Script:

#!/bin/bash
# Description: Verify email link formatting in the specific file and line mentioned.

# Test: Ensure that the email link is correctly formatted in the file `backend/lib/azimutt_web/templates/organization/billing.html.heex`.
rg --type html 'mailto:\#\{Azimutt.config\(:enterprise_support_email\)\}' backend/lib/azimutt_web/templates/organization/billing.html.heex

Length of output: 369


18-18: Verify email link formatting.

Ensure that the email link for contacting support is correctly formatted.

INSTALL.md (3)

180-180: Verify new environment variable documentation.

Ensure that the new environment variable ORGANIZATION_DEFAULT_PLAN is correctly documented.

Verification successful

Verified new environment variable documentation.

The new environment variable ORGANIZATION_DEFAULT_PLAN is correctly documented in the INSTALL.md file.

  • INSTALL.md, Line 180
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify environment variable documentation.

# Test: Ensure that the new environment variable is correctly documented.
rg --type markdown $'ORGANIZATION_DEFAULT_PLAN'

Length of output: 214


132-132: Verify new environment variable documentation.

Ensure that the new environment variable LICENSE_KEY is correctly documented.

Verification successful

Verify new environment variable documentation.

The new environment variable LICENCE_KEY is correctly documented in INSTALL.md.

  • LICENCE_KEY (optional): the licence key to unlock paid features, contact us if you need one ([email protected])
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify environment variable documentation.

# Test: Ensure that the new environment variable is correctly documented.
rg --type markdown $'LICENCE_KEY'

Length of output: 161

Tools
Markdownlint

132-132: null
Bare URL used

(MD034, no-bare-urls)


158-160: Verify new environment variables documentation.

Ensure that the new environment variables CONTACT_EMAIL, SUPPORT_EMAIL, and ENTERPRISE_SUPPORT_EMAIL are correctly documented.

Verification successful

Verified new environment variables documentation.

The environment variables CONTACT_EMAIL, SUPPORT_EMAIL, and ENTERPRISE_SUPPORT_EMAIL are correctly documented in the INSTALL.md file.

  • CONTACT_EMAIL: Line 158
  • SUPPORT_EMAIL: Line 159
  • ENTERPRISE_SUPPORT_EMAIL: Line 160
Scripts executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify environment variable documentation.

# Test: Ensure that the new environment variables are correctly documented.
rg --type markdown $'CONTACT_EMAIL' && \
rg --type markdown $'SUPPORT_EMAIL' && \
rg --type markdown $'ENTERPRISE_SUPPORT_EMAIL'

Length of output: 606

Tools
LanguageTool

[uncategorized] ~160-~160: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...imutt.app`): email shown in Azimutt for high priority support ### Key features At least on...

(EN_COMPOUND_ADJECTIVE_INTERNAL)


[typographical] ~160-~160: Except for inverted sentences, ‘will us’ requires a question mark at the end of the sentence.
Context: ...mail shown in Azimutt for high priority support ### Key features At least one of aut...

(MD_PRP_QUESTION_MARK)

backend/lib/azimutt.ex (3)

98-98: LGTM!

The active_plans function correctly returns a list of active plans.


100-142: LGTM!

The changes to the limits function align with the new feature limits for different plans. However, ensure that all function calls to limits match the new structure.


31-95: LGTM!

The changes to the plans function align with the new subscription plans. However, ensure that all function calls to plans match the new structure.

backend/lib/azimutt/organizations.ex (11)

43-44: LGTM!

The changes to the get_organization_by_customer function to preload additional resources are appropriate.


272-274: LGTM!

The get_subscriptions function correctly retrieves the subscriptions for an organization using the Stripe service.


283-284: LGTM!

The use_free_trial function correctly activates the free trial for an organization.


300-314: LGTM!

The organization_overrides function correctly applies overrides to the organization plan based on the organization data.


329-339: LGTM!

The streak_overrides function correctly applies streak-based overrides to the organization plan.


342-351: LGTM!

The validate_organization_plan function correctly validates the organization plan based on various conditions.


353-369: LGTM!

The validate_clever_cloud_plan function correctly validates the Clever Cloud plan for an organization.


372-389: LGTM!

The validate_heroku_plan function correctly validates the Heroku plan for an organization.


391-411: LGTM!

The validate_stripe_plan function correctly validates the Stripe plan for an organization.


414-416: LGTM!

The validate_default_plan function correctly validates the default plan for an organization.


287-297: LGTM!

The changes to the get_organization_plan function align with the new plan attributes and validation logic. However, ensure that all function calls to get_organization_plan match the new structure.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 1819d82 and 99d9e8f.

Files selected for processing (1)
  • backend/lib/azimutt/organizations.ex (5 hunks)
Additional comments not posted (3)
backend/lib/azimutt/organizations.ex (3)

43-44: LGTM!


272-274: LGTM!


283-285: LGTM!

backend/lib/azimutt/organizations.ex Show resolved Hide resolved
backend/lib/azimutt/organizations.ex Show resolved Hide resolved
backend/lib/azimutt/organizations.ex Show resolved Hide resolved
backend/lib/azimutt/organizations.ex Show resolved Hide resolved
backend/lib/azimutt/organizations.ex Show resolved Hide resolved
@loicknuchel loicknuchel merged commit 614ef33 into main Jun 30, 2024
4 checks passed
@loicknuchel loicknuchel deleted the new-pricing branch June 30, 2024 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant