Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 28 additions & 38 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@ name: CI

on:
pull_request:
branches:
- '*'
push:
branches:
- main
branches: [ main ]

jobs:
scan_ruby:
timeout-minutes: 10
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Ruby
uses: ruby/setup-ruby@v1
Expand All @@ -25,27 +21,41 @@ jobs:
- name: Scan for common Rails security vulnerabilities
run: bin/brakeman --no-pager

- name: Scan for known security vulnerabilities in gems used
run: bin/bundler-audit

lint:
timeout-minutes: 10
runs-on: ubuntu-latest
env:
RUBOCOP_CACHE_ROOT: tmp/rubocop
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true

- name: Prepare RuboCop cache
uses: actions/cache@v5
env:
DEPENDENCIES_HASH: ${{ hashFiles('.ruby-version', '**/.rubocop.yml', 'Gemfile.lock') }}
with:
path: ${{ env.RUBOCOP_CACHE_ROOT }}
key: rubocop-${{ runner.os }}-${{ env.DEPENDENCIES_HASH }}-${{ github.ref_name == github.event.repository.default_branch && github.run_id || 'default' }}
restore-keys: |
rubocop-${{ runner.os }}-${{ env.DEPENDENCIES_HASH }}-

- name: Lint code for consistent style
run: bin/rubocop -f github

- name: Erb Lint
- name: Lint ERB for consistent style
run: bundle exec erb_lint --lint-all

test:
timeout-minutes: 10
runs-on: ubuntu-latest

services:
postgres:
image: postgres:latest
Expand All @@ -59,47 +69,27 @@ jobs:
--health-interval 10s
--health-timeout 5s
--health-retries 5
redis:
image: redis
ports: ['6379:6379']
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5

steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install --no-install-recommends -y libvips

- name: Setup Ruby
- name: Checkout code
uses: actions/checkout@v6

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: yarn

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y -qq libvips
yarn install --frozen-lockfile

- name: Run tests
env:
DATABASE_URL: postgres://postgres:password@localhost:5432/test
REDIS_URL: redis://localhost:6379/0
RAILS_ENV: test
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
run: |
# bin/rails zeitwerk:check test:prepare db:test:prepare test
bin/rails test:prepare db:test:prepare test
run: bin/rails db:test:prepare test

- name: Keep screenshots from failed system tests
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
if: failure()
with:
name: screenshots
Expand Down
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
/public/assets
/app/assets/builds/*
!/app/assets/builds/.keep
/node_modules

# Ignore master key for decrypting credentials and more.
/config/master.key
Expand All @@ -42,9 +41,6 @@

# Ignore other files
.byebug_history
yarn-error.log
yarn-debug.log*
.yarn-integrity
.DS_Store
.idea
*~
Expand Down
1 change: 0 additions & 1 deletion .node-version

This file was deleted.

3 changes: 0 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -787,9 +787,6 @@ Lint/SuppressedException:
Lint/SymbolConversion:
Enabled: true

Lint/Syntax:
Enabled: true

Lint/ToEnumArguments:
Enabled: false

Expand Down
3 changes: 0 additions & 3 deletions Brewfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
brew "postgresql@16"
brew "libpq"

# Redis - For ActionCable support (and Sidekiq, caching, etc)
brew "redis"

# Overmind (requires tmux)
brew "tmux"
brew "overmind"
Expand Down
21 changes: 14 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Project Overview

This is a Rails 8.0 API application that serves as the backend for NativeAppTemplate iOS/Android mobile applications. It's a multi-tenant SaaS application with token-based authentication, role-based authorization, and RESTful API endpoints. Ruby 4.0.1, PostgreSQL, Redis, Sidekiq.
This is a Rails 8.1 API application that serves as the backend for NativeAppTemplate iOS/Android mobile applications. It's a multi-tenant SaaS application with token-based authentication, role-based authorization, and RESTful API endpoints. Ruby 4.0.1, PostgreSQL, Solid Queue/Cable/Cache.

## Development Commands

Expand All @@ -15,7 +15,7 @@ bin/setup # Installs all dependencies, prepares database, builds assets

### Running the Application
```bash
bin/dev # Starts Rails server, CSS watcher, JS bundler, and Sidekiq workers
bin/dev # Starts Rails server, CSS watcher, JS bundler
```

### Testing
Expand All @@ -30,6 +30,12 @@ bin/rails test test/path/to/test.rb:42 # Run specific test line
bin/rubocop # Ruby code linting
bundle exec erb_lint --lint-all # ERB template linting
bin/brakeman # Security vulnerability scanning
bin/bundler-audit # Audit gems for known security defects
```

### Local CI
```bash
bin/ci # Runs setup, rubocop, bundler-audit, brakeman, tests, and seeds
```

### Database Operations
Expand Down Expand Up @@ -69,9 +75,10 @@ bin/rails dbconsole # Database console
- State machines implemented with AASM gem

### Background Processing
- Sidekiq for background jobs with Redis backend
- Queue priorities: critical (10), mailers (5), default (2), low (1)
- Monitor at `/madmin/sidekiq` in development
- Solid Queue for background jobs (database-backed, no Redis needed)
- Solid Cable for Action Cable (database-backed)
- Solid Cache for caching in production/staging
- Monitor jobs at `/madmin/jobs` (Mission Control)

### Testing Strategy
- Minitest for all tests (models, controllers, integration, policies)
Expand All @@ -92,7 +99,7 @@ bin/rails dbconsole # Database console
- Server binds to specific IP: `192.168.1.21:3000` (not localhost)
- Mailbin for email testing at `/mailbin`
- Admin interface at `/madmin`
- Hot reload for CSS/JS changes via yarn watchers
- Tailwind CSS compiled by tailwindcss-rails gem

### Important Conventions
- Use `seed-fu` for database seeding (not standard Rails seeds)
Expand All @@ -105,7 +112,7 @@ bin/rails dbconsole # Database console
- Configured for Render.com deployment
- Build script: `bin/render-build.sh`
- Web server: `bin/render-start.sh`
- Background workers: `bin/render-start-sidekiq.sh`
- Solid Queue runs in Puma via `SOLID_QUEUE_IN_PUMA=true`

## Code Quality Checks Before Committing

Expand Down
26 changes: 14 additions & 12 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby file: ".ruby-version"

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem "rails", "~> 8.0.0"
gem "rails", "~> 8.1"

gem "propshaft", "~> 1.0"

# Use postgresql as the database for Active Record
gem "pg"

# Use the Puma web server [https://github.com/puma/puma]
gem "puma", "~> 6.0"
gem "puma", "~> 7.0"

# Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev]
gem "turbo-rails", "~> 2.0.3"
Expand All @@ -23,11 +23,11 @@ gem "stimulus-rails", "~> 1.0", ">= 1.0.2"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder", "~> 2.12"

# Use Redis adapter to run Action Cable in production
gem "redis", "~> 5.1"

# Use Kredis to get higher-level data types in Redis [https://github.com/rails/kredis]
# gem "kredis"
# Solid adapters for queue, cache, and cable (database-backed, no Redis needed)
gem "solid_queue"
gem "solid_cable"
gem "solid_cache"
gem "mission_control-jobs"

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem "tzinfo-data", platforms: %i[windows jruby]
Expand All @@ -50,16 +50,15 @@ gem "aasm"
# https://github.com/aasm/aasm
gem "after_commit_everywhere", "~> 1.4"
gem "config"
gem "sidekiq"
gem "acts_as_tenant"
gem "inline_svg", "~> 1.6"
gem "pagy", "~> 9.0"
gem "seed-fu", "~> 2.3"
gem "whenever", require: false
gem "madmin", github: "excid3/madmin"
gem "valid_email2"
gem "cssbundling-rails", "~> 1.4.0"
gem "jsbundling-rails", "~> 1.3.0"
gem "importmap-rails"
gem "tailwindcss-rails", "~> 3.0"
gem "rack-attack"
# Fix LoadError: cannot load such file -- csv
gem "csv", "~> 3.3"
Expand All @@ -68,6 +67,9 @@ group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", platforms: %i[mri windows]

# Audits gems for known security defects (use config/bundler-audit.yml to ignore issues)
gem "bundler-audit", require: false

# Static analysis for security vulnerabilities [https://brakemanscanner.org/]
gem "brakeman", require: false

Expand All @@ -78,8 +80,8 @@ group :development, :test do

gem "mailbin"

# Constrain minitest to 5.x for Rails 7.2 compatibility
gem "minitest", "~> 5.0"
# minitest 6.x extracted mock to a separate gem
gem "minitest-mock"

# Optional debugging tools
# gem "byebug", platforms: [:mri, :mingw, :x64_mingw]
Expand Down
Loading