From d973651cebf01609ebc5b80f849d1966affdc302 Mon Sep 17 00:00:00 2001 From: "Restarone Solutions Inc. Software Engineering" Date: Sat, 13 Dec 2025 13:24:15 -0500 Subject: [PATCH 1/2] day 0 guide --- DAY_0_GUIDE.md | 496 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 496 insertions(+) create mode 100644 DAY_0_GUIDE.md diff --git a/DAY_0_GUIDE.md b/DAY_0_GUIDE.md new file mode 100644 index 000000000..41a1573b0 --- /dev/null +++ b/DAY_0_GUIDE.md @@ -0,0 +1,496 @@ +# Violet Rails Day 0 Guide: From Setup to Release + +## Overview + +This guide documents the complete Day 0 story for Violet Rails - from downloading and setting up the project, through development and contribution, to releasing changes using Shape Up methodology from Basecamp. + +## Table of Contents + +1. [VM Setup & Repository Clone](#vm-setup--repository-clone) +2. [Initial Setup & Getting Started](#initial-setup--getting-started) +3. [Development Workflow](#development-workflow) +4. [Contribution Process](#contribution-process) +5. [Code Review & Merging](#code-review--merging) +6. [Release Methodology: Shape Up](#release-methodology-shape-up) +7. [Complete Day 0 Checklist](#complete-day-0-checklist) + +--- + +## VM Setup & Repository Clone + +### Prerequisites + +Before starting, ensure you have: +- Docker and Docker Compose installed +- Git configured with your SSH keys +- A GitHub account +- At least 8GB RAM available for Docker + +### Step 1: Clone the Repository + +```bash +# Clone the repository using SSH (recommended) +git clone git@github.com:restarone/violet_rails.git + +# Or using HTTPS +git clone https://github.com/restarone/violet_rails.git + +# Navigate into the project directory +cd violet_rails +``` + +### Step 2: Verify Repository Structure + +```bash +# Check the repository structure +ls -la + +# Verify git remotes +git remote -v + +# Check recent commits +git log --oneline -5 +``` + +### Step 3: Create Your Development Branch + +```bash +# Create and switch to your feature branch +git checkout -b feature/your-feature-name + +# Or for a bug fix +git checkout -b fix/issue-description +``` + +--- + +## Initial Setup & Getting Started + +### Step 1: Docker Setup + +Violet Rails uses Docker for development environment consistency: + +```bash +# Build the Docker containers +docker-compose build + +# Start all services +docker-compose up + +# Attach to the main application container (in separate terminal) +docker attach solutions_app +``` + +### Step 2: Database Setup + +```bash +# Create the database +docker-compose run --rm solutions_app rails db:create + +# Run migrations +docker-compose run --rm solutions_app rails db:migrate + +# Seed the database with initial data +docker-compose run --rm solutions_app rails db:seed +``` + +### Step 3: Asset Precompilation + +This step needs to be done only once and takes 5-20 minutes: + +```bash +docker-compose run --rm solutions_app rails assets:precompile +``` + +### Step 4: Access the Application + +You can access Violet Rails in three ways: + +- **`localhost:80`** - With Nginx load balancing +- **`lvh.me:5250`** - For testing subdomains (e.g., `violet.lvh.me:5250`) +- **`localhost:5250`** - Direct Puma server access + +### Step 5: Login Credentials + +After seeding, you can login with: +- **URL**: `lvh.me:5250/admin` or `localhost:5250/admin` +- **Email**: `violet@rails.com` +- **Password**: `123456` + +### Step 6: Environment Configuration + +Create `.env.development` file for local environment variables: + +```bash +RAILS_ENV=development +DATABASE_HOST=solutions_db +DATABASE_USERNAME=postgres +DATABASE_PASSWORD=password +DATABASE_NAME=r_solutions_development +DATABASE_PORT=5432 +APP_HOST=localhost +REDIS_URL=redis://solutions_redis:6379/12 +RACK_TIMEOUT_SERVICE_TIMEOUT=200 +``` + +--- + +## Development Workflow + +### Common Development Commands + +#### Console Access +```bash +# Rails console +docker-compose run --rm solutions_app rails c + +# Attach to running app for debugging +docker attach solutions_app + +# Sidekiq logs +docker attach solutions_sidekiq +``` + +#### Testing +```bash +# Create test database +docker-compose run --rm solutions_test rails db:create +docker-compose run --rm solutions_test rails db:migrate + +# Run full test suite +./clean_run_tests.sh + +# Run Rails tests only +docker-compose run --rm solutions_test rails test + +# Run specific test +docker-compose run --rm solutions_test rails test path/to/test.rb +``` + +#### Database Operations +```bash +# Create new migration +docker-compose run --rm solutions_app rails generate migration MigrationName + +# Rollback migration +docker-compose run --rm solutions_app rails db:rollback + +# Reset database +docker-compose run --rm solutions_app rails db:reset +``` + +### Multi-Tenant Development + +Violet Rails uses PostgreSQL schemas for multi-tenancy. When writing rake tasks: + +```ruby +desc "Example multi-tenant task" +task :my_task => :environment do + subdomains = Subdomain.all_with_public_schema + subdomains.each do |subdomain| + Apartment::Tenant.switch subdomain.name do + # Your code here + end + end +end +``` + +### Email Testing in Development + +Access MailCatcher at `http://localhost:1080/` to view sent emails. + +--- + +## Contribution Process + +### Step 1: Fork the Repository + +1. Go to https://github.com/restarone/violet_rails +2. Click "Fork" in the top right +3. Clone your fork locally +4. Add upstream remote: + +```bash +git remote add upstream git@github.com:restarone/violet_rails.git +``` + +### Step 2: Create Feature Branch + +```bash +# Sync with upstream +git fetch upstream +git checkout master +git merge upstream/master + +# Create your feature branch +git checkout -b feature/your-feature-name +``` + +### Step 3: Development Process + +1. **Make your changes** following existing code conventions +2. **Write tests** for new functionality +3. **Run the test suite** to ensure nothing breaks: + ```bash + ./clean_run_tests.sh + ``` +4. **Test manually** in the browser +5. **Check code coverage** - generated in `coverage/` directory + +### Step 4: Commit Your Changes + +```bash +# Stage your changes +git add . + +# Commit with descriptive message +git commit -m "Add feature description + +- Explain what the feature does +- Reference any related issues +- Include any breaking changes" +``` + +--- + +## Code Review & Merging + +### Step 1: Create Pull Request + +1. Push your branch to your fork: + ```bash + git push origin feature/your-feature-name + ``` + +2. Open a pull request targeting `restarone/violet_rails:master` + +### Step 2: PR Requirements + +Your PR must include: + +#### โœ… Required CI Tests Passing +- All automated tests must pass +- No breaking changes to existing functionality + +#### ๐Ÿ“ Description References Issue +- Clear description of what the PR does +- References related issue numbers +- Includes demo video for new features or bug fixes + +#### ๐Ÿงช Includes Tests +- New code paths must have test coverage +- Tests should exercise the functionality thoroughly + +#### โœ… Ready to Merge +- No merge conflicts +- Branch is up-to-date with `master` + +### Step 3: Review Process + +#### Automated Checks +- **Ruby Tests**: Multiple Ruby/Node.js versions +- **Schema Validation**: Ensures migrations are committed +- **Asset Compilation**: Verifies frontend builds +- **Security Scan**: Brakeman analysis + +#### Review App Deployment +Add the `deploy-review-app` label to launch an isolated testing environment: +1. Add label to your PR +2. GitHub Action creates temporary deployment +3. Test your changes in isolation +4. Share link with stakeholders + +#### Code Coverage Report +1. Click "Details" on Ruby test job in GitHub Actions +2. Download and open `coverage/index.html` +3. Review coverage for your changes + +### Step 4: Merge Process + +Once approved: +1. **Review app** is validated by team +2. **Changes** are merged to `rc` branch for staging +3. **Internal testing** on `restarone.solutions` +4. **Final merge** to `master` for production + +--- + +## Release Methodology: Shape Up + +Violet Rails uses Basecamp's Shape Up methodology for releases. This approach focuses on shipping meaningful work in fixed-time cycles. + +### Core Concepts + +#### ๐Ÿ”„ Six-Week Cycles +- **Fixed time, variable scope** +- Teams work uninterruptedly on shaped projects +- Long enough to finish something meaningful +- Short enough to feel deadline pressure + +#### ๐ŸŽฏ Shaping the Work +Before betting on a project: + +1. **Set Boundaries**: Define the "appetite" (time budget) +2. **Find Elements**: Rough solutions at right level of abstraction +3. **Address Risks**: Identify and eliminate rabbit holes +4. **Write the Pitch**: Document problem, appetite, solution, and risks + +#### ๐ŸŽฒ Betting, Not Backlogs +- No traditional backlogs +- **Betting Table**: Stakeholders decide which pitches to bet on +- **Circuit Breaker**: Projects that don't ship in one cycle are canceled by default +- **Clean Slate**: Each cycle starts fresh + +#### ๐Ÿ—๏ธ Building Phase +- **Assign Projects, Not Tasks**: Teams own the entire project +- **Done Means Deployed**: Project isn't done until it's shipped +- **Hill Chart Progress**: Visualize work from unknown to done + +### Violet Rails Release Cycle + +#### Phase 1: Cool Down (2 weeks) +- Fix bugs and address issues +- Hold **Betting Table** meetings +- Shape projects for next cycle +- Plan upcoming work + +#### Phase 2: Development Cycle (6 weeks) +- Teams work on shaped projects +- No interruptions or context switching +- Weekly progress check-ins +- Scope management within timebox + +#### Phase 3: Integration & Release +- **Staging Deployment**: Merge to `rc` branch +- **Internal Testing**: Validate on staging environment +- **Production Release**: Merge to `master` branch +- **Monitoring**: Post-release observation + +### Release Branch Strategy + +```bash +# Development happens on feature branches +git checkout -b feature/new-feature + +# Merge to rc for staging +git checkout rc +git merge feature/new-feature +git push origin rc + +# After staging validation, merge to master +git checkout master +git merge rc +git push origin master +``` + +### Automated Deployment Triggers + +- **`rc` branch** โ†’ Staging environment (`restarone.solutions`) +- **`master` branch** โ†’ Production environments (multiple clients) + +### Quality Gates + +Each release must pass: +1. โœ… All automated tests +2. โœ… Security scans (Brakeman) +3. โœ… Code coverage requirements +4. โœ… Manual QA on staging +5. โœ… Performance benchmarks +6. โœ… Documentation updates + +--- + +## Complete Day 0 Checklist + +### โœ… VM & Repository Setup +- [ ] Docker and Docker Compose installed +- [ ] Repository cloned from GitHub +- [ ] Development branch created +- [ ] Upstream remote configured + +### โœ… Initial Setup +- [ ] Docker containers built successfully +- [ ] Database created and migrated +- [ ] Database seeded with initial data +- [ ] Assets precompiled +- [ ] Application accessible in browser +- [ ] Environment variables configured +- [ ] Login credentials working + +### โœ… Development Environment +- [ ] Rails console accessible +- [ ] Test database created +- [ ] Test suite runs successfully +- [ ] Code coverage reports generating +- [ ] Email testing via MailCatcher +- [ ] Debugging with byebug/pry working + +### โœ… Contribution Workflow +- [ ] Fork created on GitHub +- [ ] Git workflow understood +- [ ] Code conventions reviewed +- [ ] Testing requirements understood +- [ ] Commit message format learned + +### โœ… Code Review Process +- [ ] PR requirements understood +- [ ] Review app deployment process learned +- [ ] Code coverage review process known +- [ ] Merge process documented + +### โœ… Shape Up Methodology +- [ ] Six-week cycle concept understood +- [ ] Shaping process learned +- [ ] Betting table concept grasped +- [ ] Release branch strategy understood +- [ ] Quality gates identified + +### ๐Ÿš€ Ready for Day 1 + +You're now fully set up to: +- Develop features on Violet Rails +- Contribute to the codebase effectively +- Participate in the release process +- Understand the product development methodology + +--- + +## Quick Reference Commands + +```bash +# Start development +docker-compose up && docker attach solutions_app + +# Run tests +./clean_run_tests.sh + +# Create migration +docker-compose run --rm solutions_app rails g migration Name + +# Console access +docker-compose run --rm solutions_app rails c + +# Database reset +docker-compose run --rm solutions_app rails db:reset + +# Asset precompilation +docker-compose run --rm solutions_app rails assets:precompile + +# Git workflow +git checkout -b feature/name +git add . +git commit -m "Description" +git push origin feature-name +``` + +## Support & Resources + +- **Main Documentation**: [README.md](README.md) +- **Development Wiki**: [Getting Started Guide](https://github.com/restarone/violet_rails/wiki/Getting-started-(development-cheatsheet)) +- **Shape Up Book**: [Shape Up by Basecamp](https://basecamp.com/shapeup) +- **Issues**: [GitHub Issues](https://github.com/restarone/violet_rails/issues) +- **Discussions**: [GitHub Discussions](https://github.com/restarone/violet_rails/discussions) + +--- + +*This guide represents the complete Day 0 experience for Violet Rails, from initial setup to understanding the full development and release lifecycle.* \ No newline at end of file From 09e3b14584e27c172ecd05b8858ff068f39a69b3 Mon Sep 17 00:00:00 2001 From: "Restarone Solutions Inc. Software Engineering" Date: Sat, 13 Dec 2025 13:31:45 -0500 Subject: [PATCH 2/2] first issue --- GOOD_FIRST_ISSUES.md | 402 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 402 insertions(+) create mode 100644 GOOD_FIRST_ISSUES.md diff --git a/GOOD_FIRST_ISSUES.md b/GOOD_FIRST_ISSUES.md new file mode 100644 index 000000000..4ee9c7386 --- /dev/null +++ b/GOOD_FIRST_ISSUES.md @@ -0,0 +1,402 @@ +# Violet Rails: Good First Issues & Contribution Guide + +## ๐ŸŽฏ 5 Good First Issues for New Contributors + +Based on my analysis of the Violet Rails codebase, here are 5 well-scoped, low-risk issues perfect for new contributors: + +### 1. **Remove TODO Comments and Clean Up Code** (Easy) +**Files & Locations:** +- `app/graphql/types/mutation_type.rb:3` - Remove test field +- `config/initializers/sidekiq.rb:3` - Implement Current attribute persistence +- `app/services/webhook/verification_method/custom.rb:12` - Fix validation return format +- `app/graphql/r_solutions_schema.rb:19` - Implement resolve_type method + +**Why it's good for beginners:** +- Clear, isolated changes +- No complex business logic +- Immediate impact on code quality +- Easy to test and validate + +**Implementation approach:** +```ruby +# Example: Remove test field from mutation_type.rb +# field :test_field, String, null: true # <- DELETE THIS LINE +``` + +### 2. **Add Missing Test Coverage** (Easy to Medium) +**Files & Locations:** +- `test/models/sales_asset_test.rb` - Only placeholder test exists +- `test/models/message_test.rb` - Only placeholder test exists +- `test/models/message_thread_test.rb` - Only placeholder test exists +- `test/models/mailbox_test.rb` - Only placeholder test exists + +**Why it's good for beginners:** +- Well-defined models to test +- Clear validation rules to cover +- Rails testing patterns are well-documented +- Immediate impact on code coverage metrics + +**Example test structure:** +```ruby +# test/models/sales_asset_test.rb +require "test_helper" + +class SalesAssetTest < ActiveSupport::TestCase + test "should be valid with all attributes" do + sales_asset = SalesAsset.new( + name: "Test Asset", + width: 100, + height: 100, + html: "
Test
" + ) + assert sales_asset.valid? + end + + test "should validate presence of name" do + sales_asset = SalesAsset.new + assert_not sales_asset.valid? + assert_includes sales_asset.errors[:name], "can't be blank" + end +end +``` + +### 3. **Fix Broad Exception Handling** (Easy to Medium) +**Files & Locations:** +- `app/models/api_action.rb:113,128,142` - Replace generic rescues +- `app/models/api_namespace.rb:219,358` - Replace generic rescues +- `app/models/ahoy/event.rb:110` - Replace generic rescue + +**Why it's good for beginners:** +- Clear pattern to follow +- Improves error handling and debugging +- Low risk of breaking existing functionality +- Teaches Rails exception handling best practices + +**Before:** +```ruby +rescue => e + Rails.logger.error "Something went wrong: #{e.message}" +end +``` + +**After:** +```ruby +rescue ActiveRecord::RecordNotFound => e + Rails.logger.error "Record not found: #{e.message}" +rescue StandardError => e + Rails.logger.error "Unexpected error: #{e.message}" +end +``` + +### 4. **Optimize Database Queries** (Easy) +**Files & Locations:** +- `app/models/subdomain.rb:238-239` - Replace `.all.each` with `find_each` +- `app/models/api_namespace.rb:149` - Replace `.each` with `find_each` + +**Why it's good for beginners:** +- Clear performance improvement +- Simple pattern replacement +- Teaches Rails memory management +- Easy to measure impact + +**Before:** +```ruby +Subdomain.all.each do |subdomain| + # process subdomain +end +``` + +**After:** +```ruby +Subdomain.find_each do |subdomain| + # process subdomain +end +``` + +### 5. **Remove Deprecated Ember Integration Tests** (Easy) +**Files & Locations:** +- `test/integration/ember/ember_js_renderer_test.rb:6,16` - Remove skipped tests + +**Why it's good for beginners:** +- Clear removal of dead code +- No risk of breaking functionality +- Improves test suite performance +- Simple file deletion/commenting + +--- + +## โš ๏ธ Critical Footguns to Avoid + +### 1. **Multi-Tenancy Complexity** +**Footgun:** Violet Rails uses PostgreSQL schemas for multi-tenancy via the `apartment` gem. + +**What can go wrong:** +- Running migrations in wrong schema +- Data leakage between tenants +- Cross-tenant data access + +**How to avoid:** +```ruby +# ALWAYS wrap tenant-specific operations +Apartment::Tenant.switch(subdomain.name) do + # Your code here +end + +# NEVER access data directly without switching +User.all # BAD - accesses public schema +``` + +### 2. **Docker Development Environment** +**Footgun:** Complex Docker setup with multiple services. + +**What can go wrong:** +- Database connection issues +- Asset compilation failures +- Container networking problems + +**How to avoid:** +```bash +# Always use the full docker-compose commands +docker-compose run --rm solutions_app rails db:migrate +# NOT: rails db:migrate (runs outside container) + +# Attach to correct container +docker attach solutions_app +# NOT: running commands locally +``` + +### 3. **Asset Pipeline Complexity** +**Footgun:** Violet Rails uses Webpacker with Ember.js frontend. + +**What can go wrong:** +- Asset compilation failures +- JavaScript errors breaking admin UI +- CSS not updating + +**How to avoid:** +```bash +# Always precompile after major changes +docker-compose run --rm solutions_app rails assets:precompile + +# Check both Rails and Ember builds +docker-compose run --rm solutions_app rails assets:clobber +docker-compose run --rm solutions_app rails assets:precompile +``` + +### 4. **Sidekiq Background Jobs** +**Footgun:** Background job processing with complex dependencies. + +**What can go wrong:** +- Jobs failing silently +- Memory leaks in long-running jobs +- Incorrect job retry logic + +**How to avoid:** +```ruby +# Always handle specific exceptions +class MyJob < ApplicationJob + retry_on StandardError, wait: :exponentially_longer + + def perform(*args) + # Your code here + rescue ActiveRecord::RecordNotFound => e + # Handle specific case + end +end +``` + +### 5. **GraphQL Schema Evolution** +**Footgun:** GraphQL API with custom types and mutations. + +**What can go wrong:** +- Breaking changes to existing queries +- Type conflicts +- N+1 query problems + +**How to avoid:** +```ruby +# Always test GraphQL changes +# Use GraphQL Playground for testing +# Check for N+1 queries with bullet gem +``` + +--- + +## ๐Ÿš€ Getting Your Contribution Merged + +### Step 1: Setup Development Environment +```bash +# 1. Clone and setup +git clone git@github.com:restarone/violet_rails.git +cd violet_rails + +# 2. Docker setup (takes 15-20 minutes) +docker-compose build + +# 3. Database setup +docker-compose run --rm solutions_app rails db:create db:migrate db:seed + +# 4. Asset compilation (5-20 minutes) +docker-compose run --rm solutions_app rails assets:precompile + +# 5. Start development +docker-compose up +# In new terminal: docker attach solutions_app +``` + +### Step 2: Create Your Branch +```bash +git checkout -b fix/issue-description +# or +git checkout -b feature/feature-name +``` + +### Step 3: Make Your Changes +1. **Follow existing code patterns** - Look at similar files for conventions +2. **Write tests** - All new code needs test coverage +3. **Run test suite** - Ensure nothing breaks: + ```bash + ./clean_run_tests.sh + ``` + +### Step 4: Quality Checks +```bash +# 1. Run full test suite +./clean_run_tests.sh + +# 2. Check code coverage (generated in coverage/ directory) +open coverage/index.html + +# 3. Test manually in browser +# Access at http://lvh.me:5250/admin +# Login: violet@rails.com / 123456 + +# 4. Check for security issues +docker-compose run --rm solutions_app bundle exec brakeman +``` + +### Step 5: Commit and Push +```bash +git add . +git commit -m "Fix: Replace broad exception handling with specific exceptions + +- Replace rescue => e with specific exception types +- Improve error logging and debugging +- Addresses code quality issues in api_action.rb and api_namespace.rb + +Closes #[issue-number]" +``` + +### Step 6: Create Pull Request +1. Push to your fork: `git push origin fix/issue-description` +2. Open PR targeting `restarone/violet_rails:master` +3. **Add `deploy-review-app` label** to launch testing environment +4. Fill out PR template completely +5. Include demo video if applicable + +### Step 7: Review Process +1. **Automated checks must pass:** + - Ruby tests (multiple versions) + - Node.js tests + - Security scan (Brakeman) + - Asset compilation + +2. **Manual review:** + - Code quality and conventions + - Test coverage + - Documentation updates + +3. **Review app testing:** + - Your PR will be deployed to isolated environment + - Test your changes thoroughly + - Share link with reviewers + +### Step 8: Merge Process +1. **PR approved** โ†’ Merged to `rc` branch +2. **Staging deployment** โ†’ Internal testing on `restarone.solutions` +3. **Production release** โ†’ Merged to `master` branch + +--- + +## ๐Ÿ“‹ Pre-Merge Checklist + +### Code Quality +- [ ] Follows existing code conventions +- [ ] No RuboCop offenses +- [ ] No Brakeman security warnings +- [ ] Tests cover new functionality +- [ ] Documentation updated if needed + +### Testing +- [ ] All tests pass locally: `./clean_run_tests.sh` +- [ ] Code coverage maintained or improved +- [ ] Manual testing completed in browser +- [ ] Edge cases considered and tested + +### Multi-Tenancy +- [ ] Tenant isolation maintained +- [ ] No cross-tenant data access +- [ ] Proper schema switching used + +### Performance +- [ ] No N+1 queries introduced +- [ ] Database queries optimized +- [ ] Memory usage considered + +### Security +- [ ] No sensitive data exposed +- [ ] Proper authorization checks +- [ ] Input validation present +- [ ] SQL injection prevention + +--- + +## ๐ŸŽฏ Quick Wins for First-Time Contributors + +### The Easiest First Issue +**Remove TODO comment from GraphQL mutation type:** +1. Open `app/graphql/types/mutation_type.rb` +2. Delete line 3: `field :test_field, String, null: true` +3. Run tests: `./clean_run_tests.sh` +4. Commit and PR + +### Why This is Perfect: +- 1 line change +- No complex logic +- Tests will immediately validate +- Teaches the full contribution workflow +- Builds confidence for larger changes + +--- + +## ๐Ÿ“ž Getting Help + +### Resources +- **Development Wiki**: https://github.com/restarone/violet_rails/wiki/Getting-started-(development-cheatsheet) +- **Day 0 Guide**: `DAY_0_GUIDE.md` in repository +- **Contributing Guide**: `CONTRIBUTING.md` in repository + +### Common Issues +1. **Docker build fails** โ†’ Check Docker Desktop is running +2. **Database connection errors** โ†’ Verify `.env.development` file +3. **Asset compilation fails** โ†’ Run `rails assets:clobber` then retry +4. **Tests fail** โ†’ Check if database is properly migrated + +### Community +- **GitHub Issues**: Report bugs and request features +- **GitHub Discussions**: Ask questions and share ideas +- **Review Apps**: Test changes in isolated environments + +--- + +## ๐Ÿ† Success Metrics + +Your contribution is successful when: +1. โœ… All automated tests pass +2. โœ… Code coverage is maintained +3. โœ… Review app works correctly +4. โœ… PR is merged to `rc` branch +5. โœ… Changes deploy to staging successfully +6. โœ… Final merge to `master` branch + +Welcome to Violet Rails open source! ๐ŸŽ‰ \ No newline at end of file