/cami

Account Management Service

Primary LanguageRuby

Customer Accounts Management & Invoicing MVP

Reference template: https://github.com/IsraelDCastro/rails-vite-tailwindcss-template

Ruby Version

  • 3.2.2

Service/Vendor dependencies

  • Ngrok for local development tunneling

System Dependencies

System dependencies are defined in the following configuration files:

  • .tool-versions (see .tool-versions.example)
  • Gemfile
  • Brewfile
  • package.json
    • yarn.lock

Configuration

Development service ports

Service Port
Rails 16006
Redis 16079
Postgres (app store) 16032
MongoDB (invoicing score) 16017

Running the app for the first time

1. Setup the environment

If you use asdf, you will also need to setup the following plugins and install their corresponding versions with the asdf install command:

Review the .env.example file to ensure the environment variables are set. You can control which variables are made available in each environment while working locally using the following files:

  • .env.local
  • .env.test

The .envrc (see .envrc.example) file should be included for compatibility with other features like docker compose and simply sources the .env.local file.

2. Install dependencies

# Install system dependencies
brew bundle
# Setup the ASDF dependencies file
cp -v .tool-versions.example .tool-versions
# Set bundler location
bundle config set --local path ./vendor/bundle
# Install Ruby dependencies
bundle install
# Install Node dependencies
yarn install

3. Setup a GPG key for your Github account

Follow this guide. This will be needed by the application when it uses the git-crypt command to secure secret fixture files.

4. Setup your application secrets

Search for development.yml.enc to locate the entry in the KeePass store with the application's encrypted secrets files.

Run the following code to update the application for the corresponding environments. You will need to do this before running the test suite.

# Help menu for the secrets command
bin/thor help lx-cli:secrets:edit
# Edit the secrets file (for the development environment)
bin/thor lx-cli:secrets:edit --environment development

5. Start up the application's services

bin/start-docker

6. Initialize the database

# Get help with the DB setup command
bin/thor help lx-cli:db:setup
# Initialize the app store database
bin/thor lx-cli:db:setup --postgres
# Initialize the invoicing score database
bin/thor lx-cli:db:setup --mongodb

7. Start up the app

You can also start up the app's non-dockerized services with the included IDE configurations for RubyMine in the .ide-configs folder.

This is the same command you'll need any time you want to start up the application:

bin/dev

Running Storybook

The FeatureFlagsProvider requires the application service running locally on port 6006 (currently broken, hence all features are disabled by default). This should be refactored to mock the response from /api/features and other endpoints needed to review components. See this guide on mocking requests for more.

To review component stories, run:

yarn storybook

Database management

Review the list of available tasks for managing the MongoDB document store:

bundle exec rails -T | grep mongoid

# Sample output
rails db:mongoid:create_collections             # Create collections for Mongoid models
rails db:mongoid:create_collections:force       # Drop and create collections for Mongoid models
rails db:mongoid:create_indexes                 # Create indexes specified in Mongoid models
rails db:mongoid:drop                           # Drop the database of the default Mongoid client
rails db:mongoid:purge                          # Drop all non-system collections
rails db:mongoid:remove_indexes                 # Remove indexes specified in Mongoid models
rails db:mongoid:remove_undefined_indexes       # Remove indexes that exist in the database but are not specified in Mongoid models
rails db:mongoid:shard_collections              # Shard collections with shard keys specified in Mongoid models

Setting up the document store in the test environment

This guide is intended as a temporary solution until we can come up with something better for bringing up the document store with the right set of permissions the first time the application setup is run.

# Show help menu for mongosh
docker exec -it mongodb.accounts.larcity mongosh --help

# Run the command to initialize the database
docker exec -it mongodb.accounts.larcity mongosh \
  --authenticationDatabase admin
  --file ./development/mongodb/docker-entrypoint-initdb.d/init-doc-stores
  --username <MONGO_INITDB_ROOT_USERNAME>
  --password <MONGO_INITDB_ROOT_PASSWORD>

# Run the command to connect the mongodb container
bin/thor lx-cli:db:connect --mongodb

Once connected to the database instance, run the following commands to setup test credentials:

// List databases
show dbs

// Use the admin database
use admin

// Create a new user
db.createUser({
  user: "db_admin",
  pwd: `${process.env.MONGO_INITDB_ROOT_PASSWORD}`,
  roles: [
    { role: "dbOwner", db: "doc_store_development" },
    { role: "dbOwner", db: "doc_store_test" },
  ]
})

use doc_store_test

// Create a new user (for testing purposes)
db.createUser({
  user: "db_admin",
  pwd: passwordPrompt(),
  roles: [
    { role: "dbOwner", db: "doc_store_test" }
  ]
})

use doc_store_development

// Create a new user (for development purposes)
db.createUser({
  user: "db_admin",
  pwd: passwordPrompt(),
  roles: [
    { role: "dbOwner", db: "doc_store_development" }
  ]
})

// Example: Grant roles to an existing user
db.grantRolesToUser("db_admin", ["dbOwner"])

Resetting the databases

# To reset the active record database
bundle exec rails db:reset db:seed
# To reset the app store database
bundle exec rails db:mongoid:purge

Managing the document store

A few helpful commands for managing the document store.

bundle exec rails mongoid --help

How to run the test suite

TODO: Add test suite instructions

Services (job queues, cache servers, search engines, etc.)

TODO: Add services

Deployment instructions

TODO: Add deployment instructions

Development

Managing application secrets

To edit credentials in your IDE, run the following command in your console:

bin/thor lx-cli:secrets:edit

To view help information about managing application credentials, run the following command in your console:

bin/rails credentials:help

To edit the credentials file for your development environment using the rails credentials scripts and your command line, run the following code in your console:

EDITOR=nano bin/rails credentials:edit --environment ${RAILS_ENV:-development}

Testing emails

To enable email testing, set SEND_EMAILS_ENABLED=yes in your .env.local file.

To test emails in development, you can use the Mailhog service. If you are using the RubyMine configurations you will already have a dockerized Mailhog server running in debug mode. Otherwise, to start the service, run the following command in your console:

docker compose up -d mailhog

Your test inbox will be available at http://localhost:8025.

Using NGROK

Follow these steps to setup ngrok for your local environment:

  • Ensure you have updated your .envrc file with the NGROK_AUTH_TOKEN. You can get this from KeePass

  • Run the following script to export the token to your local ngrok.yml config file:

    ngrok config add-authtoken ${NGROK_AUTH_TOKEN}

Then you can open a tunnel to your local environment by running:

thor lx-cli:tunnel:open_all

Generating a Monogid Model

rails g model Invoice --orm=mongoid

After generating the model, if you would like to inherit application functionality for document records, you can include the DocumentRecord concern in the model:

class Invoice
  include DocumentRecord
end

Print key file

bin/thor help lx-cli:secrets:print_key

Handling fixture files

A few helpful commands for handling fixture files.

Sanitizing an existing fixture file

# Show help menu for the sanitize command
bin/thor help lx-cli:fixtures:sanitize

# Sanitize the fixture file (outputs to the same directory as the fixture)
bin/thor lx-cli:fixtures:sanitize --file ./path/to/fixture.yml

Converting a JSON fixture file to a YAML fixture file

You can review this guide for more tips on using the yq command to transform (fixture) files.

# Convert the JSON fixture file to a YAML fixture file
yq -p json -o yaml ./path/to/fixture.json > ./path/to/fixture.yml

FAQs

RubyMine

How do I disable these "Missing type signature" errors?

Go to Settngs | Editor | Inspections | Ruby | RBS and uncheck Missing type signature

Integration Partners

PayPal

Guides and References

Known issues

Issues with ESM Support

Link to a helpful comment on a related Github issue: yarnpkg/yarn#8994 (comment)

Each time a new dependency is added, you'll need to nuke the yarn.lock file before yarn test is able to run successfully again. The error looks like this:

yarn run v1.22.21
$ jest
Error [ERR_REQUIRE_ESM]: require() of ES Module /opt/Developer/@larcity/account_manager/node_modules/string-width/index.js from /opt/Developer/@larcity/account_manager/node_modules/cliui/build/index.cjs not supported.
Instead change the require of index.js in /opt/Developer/@larcity/account_manager/node_modules/cliui/build/index.cjs to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> (/opt/Developer/@larcity/account_manager/node_modules/cliui/build/index.cjs:291:21)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Future Work

  • A JS Auth flow to emit and retain the JWT token for frontend access control features and initialize the rails session for everything else
  • Review Yahoo + Google updated email sender requirements and make any needed changes to the Brevo configs
  • Implement forbidden rescue page (or just set a flash message and redirect to the root path)
  • "Continue with Google" quick link in the profile dropdown
  • Fix web concurrency support (issues here might be related to log streaming). Here's the error message: objc[97397]: +[NSCharacterSet initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug
  • AASM for account status
  • Setup and update production credentials in the config/credentials/production.yml.enc file
  • Implement :confirmable to secure accounts when switching/adding auth providers
  • Implement magic links
  • Implement Omniauth via apple
  • Implement FontAwesome library for SVG icons
  • Secure accounts with MFA
  • Setup secrets using docker images' compatibility with secret files
  • Vite CJS API is deprecated and will be removed in v6. Update the vite.config.js file to use the ESM build instead
  • New ESLint configuration system is available. You will need to create a new eslint.config.js file to use the new configuration system
  • Confirm account changes with OTP (email, TOTP), magic links, or passkey
  • Setup RSwag for baller request specs & API tools
  • Setup Flipper for feature flags
  • Knapsack Pro for parallelizing tests
  • Check out Redis Stack for docker for advanced indexing & search features with redis data
  • Playwright E2E test suite
  • Implement default authorization policies
  • Consolidate vite configuration & dependencies right now, vite is a dependency of both the front and backend separately. Is there a better way?
  • Address error from working on rails project in VSCode: /Users/localadmin/.asdf/installs/ruby/3.2.2/bin/ruby: warning: Ruby was built without YJIT support. You may need to install rustc to build Ruby with YJIT.