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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# Ignore bundler config.
/.bundle

# Ignore environment variables file.
.env

# Ignore all logfiles and tempfiles.
Expand All @@ -30,6 +31,7 @@
# Ignore master key for decrypting credentials and more.
/config/master.key

# Ignore node modules and build files
/public/packs
/public/packs-test
/node_modules
Expand All @@ -41,5 +43,8 @@ yarn-debug.log*
/app/assets/builds/*
!/app/assets/builds/.keep

# Ignore coverage directory
/coverage/

# Docker
/vendor/bundle
5 changes: 4 additions & 1 deletion .opencode/agents/rails-code-auditor.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Review code for quality and Rails conventions (report + suggest on request)
mode: subagent
model: opencode/minimax-m2.1-free
permission:
skill:
"rails-code-quality": "allow"
Expand All @@ -21,12 +22,14 @@ You are a Rails code auditor focused on reviewing code quality and ensuring adhe
## Your Responsibilities

### Code Quality Checks

- Run code quality tools: `bin/rubocop`
- Run security scans: `bin/brakeman`
- Review for code smells and anti-patterns
- Check against Rails best practices

### Convention Reviews

- Verify controller patterns (thin controllers, service delegation)
- Check model patterns (validations, scopes, associations)
- Review migration patterns (reversible, proper indexes)
Expand All @@ -35,6 +38,7 @@ You are a Rails code auditor focused on reviewing code quality and ensuring adhe
- Check test coverage and patterns

### Security Reviews

- Identify input validation vulnerabilities
- Check authentication and authorization
- Review data exposure risks
Expand All @@ -56,4 +60,3 @@ You are a Rails code auditor focused on reviewing code quality and ensuring adhe
- Focus on identifying issues first, then suggest on request
- Use project's existing code as reference for conventions
- Prioritize security and critical issues

5 changes: 4 additions & 1 deletion .opencode/agents/rails-migration-manager.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Manage Rails migrations - create, run, rollback, and troubleshoot
mode: subagent
model: opencode/grok-code
permission:
skill:
"rails-migrations": "allow"
Expand All @@ -17,13 +18,15 @@ You are a Rails migration manager specializing in all aspects of database migrat
## Your Responsibilities

### Creating Migrations

- Generate migrations following reversible patterns
- Use `change` method for reversible operations
- Use `up`/`down` methods for irreversible operations
- Add indexes for foreign keys and frequently queried columns
- Include proper database constraints

### Managing Migrations

- Run migrations: `rails db:migrate`
- Rollback migrations: `rails db:rollback [STEP=n]`
- View migration status: `rails db:migrate:status`
Expand All @@ -32,6 +35,7 @@ You are a Rails migration manager specializing in all aspects of database migrat
- Seed database: `rails db:seed`

### Troubleshooting

- Identify and fix migration failures
- Resolve conflicting migrations
- Handle schema changes safely
Expand All @@ -52,4 +56,3 @@ You are a Rails migration manager specializing in all aspects of database migrat
- Always test migrations in development first
- Use transactions when possible
- Provide clear descriptions of what each migration does

5 changes: 4 additions & 1 deletion .opencode/agents/rails-refactor.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Refactor code following Rails and project conventions
mode: subagent
model: opencode/glm-4.7-free
permission:
skill:
"rails-code-quality": "allow"
Expand All @@ -23,19 +24,22 @@ You are a Rails refactoring specialist focused on improving code quality while m
## Your Responsibilities

### Code Refactoring

- Extract business logic to service objects
- Refactor controllers to use service delegation
- Apply Rails conventions and patterns
- Remove code smells and anti-patterns
- Improve code organization and structure

### Performance Optimizations

- Optimize database queries (N+1 problems, eager loading)
- Improve caching strategies
- Reduce memory usage
- Optimize algorithmic complexity

### Test Improvements

- Improve test coverage
- Refactor flaky tests
- Apply testing patterns from skills
Expand All @@ -59,4 +63,3 @@ You are a Rails refactoring specialist focused on improving code quality while m
- Maintain backward compatibility when possible
- Focus on meaningful improvements, not changes for change's sake
- Ask for clarification if refactoring scope is unclear

2 changes: 1 addition & 1 deletion .opencode/agents/rails-resource-builder.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Generate complete Rails resources (models, controllers, routes, tests)
mode: subagent
model: opencode/grok-code
permission:
skill:
"rails-models": "allow"
Expand Down Expand Up @@ -54,4 +55,3 @@ Generate complete Rails resources that include:
- Follow the existing codebase conventions
- Ensure generated specs follow the `*_spec.rb` naming pattern
- Place files in appropriate directories (app/models/, app/controllers/, spec/)

4 changes: 3 additions & 1 deletion .opencode/agents/rails-test-runner.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Execute tests and report results only
mode: subagent
model: opencode/grok-code
permission:
skill:
"rspec-testing": "allow"
Expand All @@ -15,6 +16,7 @@ You are a Rails test runner focused solely on executing tests and reporting resu
## Your Responsibilities

### Running Tests

- Execute tests using `bin/rspec`
- Run all tests: `bin/rspec`
- Run specific test file: `bin/rspec spec/models/facility_spec.rb`
Expand All @@ -23,6 +25,7 @@ You are a Rails test runner focused solely on executing tests and reporting resu
- Run directory of tests: `bin/rspec spec/models/`

### Reporting Results

- Report test results clearly
- Show failures with detailed output
- Provide summary statistics (passed, failed, pending)
Expand All @@ -43,4 +46,3 @@ You are a Rails test runner focused solely on executing tests and reporting resu
- Test directory mirrors app structure
- Focus on execution and reporting, not fixing
- Use FactoryBot patterns from the skill

7 changes: 7 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,10 @@ This codebase includes specialized agents for Rails development workflows. Invok
- ViewComponent tests use `type: :component`
- System specs use Capybara and Puma

## Development Plans

See `docs/plans/README.md` for:
- Active development plans and their status
- Implementation tracking and progress metrics
- Plan documentation patterns and templates

9 changes: 6 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ group :development, :test do
gem "rspec-rails", "~> 7.1.1"
gem "shoulda-matchers", ">= 6.2.0"
gem "capybara"
gem "rails-controller-testing"

gem "factory_bot_rails", "~> 6.4.3"

# Call "byebug" anywhere in the code to stop execution and get a debugger console
gem "factory_bot_rails", "~> 6.4.3"

gem 'simplecov', require: false

# Call "byebug" anywhere in the code to stop execution and get a debugger console
gem "byebug", platforms: [:mri, :windows]
end

Expand Down
13 changes: 13 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ GEM
responders
warden (~> 1.2.3)
diff-lcs (1.6.2)
docile (1.4.1)
dotenv (3.1.8)
dotenv-rails (3.1.8)
dotenv (= 3.1.8)
Expand Down Expand Up @@ -320,6 +321,10 @@ GEM
activesupport (= 8.0.3)
bundler (>= 1.15.0)
railties (= 8.0.3)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
Expand Down Expand Up @@ -425,6 +430,12 @@ GEM
securerandom (0.4.1)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.2)
simplecov_json_formatter (0.1.4)
slop (3.6.0)
stackprof (0.2.27)
stimulus-rails (1.3.4)
Expand Down Expand Up @@ -511,6 +522,7 @@ DEPENDENCIES
rack-cors
rack-mini-profiler (~> 3.3.1)
rails (~> 8.0.3)
rails-controller-testing
redis (~> 5.4.1)
requestjs-rails
rspec-rails (~> 7.1.1)
Expand All @@ -520,6 +532,7 @@ DEPENDENCIES
rubocop-rails
rubocop-rspec
shoulda-matchers (>= 6.2.0)
simplecov
stackprof
turbo-rails
tzinfo-data
Expand Down
18 changes: 9 additions & 9 deletions app/controllers/api/zones_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ class Api::ZonesController < Api::BaseController

# GET api/zones
def index
@zones = Zone.all.includes(:facilities, :users)
@zones = Zone.includes(:facilities, :users)

@response = ZonesSerializer.new(@zones)
@response = ZonesSerializer.call(@zones)
render json: @response, status: :ok
end

# GET api/zones/:id/admin
def list_admin
@zone = Zone.find params[:id]
@zone_admins = @zone.users
@responde = { users: @zone_admins }
render json: @responde, status: :ok
@response = { users: @zone_admins }
render json: @response, status: :ok
end

# POST api/zones/:id/admin
def add_admin
@zone = Zone.find(params[:id])
@user = User.find(params[:user_id])

if @user.zones << @zone
render json: ZoneSerializer.new(@zone), status: :created
else
if @user.zones.exists?(@zone.id) || !(@user.zones << @zone)
head :conflict
else
render json: ZoneSerializer.call(@zone), status: :created
end
end

Expand All @@ -37,8 +37,8 @@ def remove_admin
@zone = Zone.find(params[:id])
@user = User.find(params[:user_id])

if @user.zones.delete @zone
render json: ZoneSerializer.new(@zone), status: :ok
if @user.zones.exists?(@zone.id) && @user.zones.delete(@zone)
render json: ZoneSerializer.call(@zone), status: :ok
else
head :conflict
end
Expand Down
43 changes: 23 additions & 20 deletions app/models/facility.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class Facility < ApplicationRecord

validates :name, presence: true

with_options if: :verified? do |verified_facility|
verified_facility.validates :lat, :long, presence: true
with_options if: :verified? do
validates :lat, :long, presence: true
end

before_validation :clean_data
Expand All @@ -42,14 +42,17 @@ class Facility < ApplicationRecord
scope :external, -> { where.not(external_id: nil) }
scope :not_external, -> { where(external_id: nil) }

def managed_by?(user)
f_user_id = if user.respond_to? :id
user.id
else
user
end
def managed_by?(user_or_user_id)
return false if user_or_user_id.blank?

f_user_id = if user_or_user_id.respond_to? :id
user_or_user_id.id
else
user_or_user_id
end

# Case Facility's User is the same
return true if this.user_id == f_user_id
return true if user_id == f_user_id
# Case Zone of the Facility has the user as admin
return true if User.find(f_user_id).manages.any?

Expand Down Expand Up @@ -113,19 +116,12 @@ def coord
GeoLocation.coord(lat, long)
end

def distance(to_coord = nil, to_lat: nil, to_long: nil, to_facility: nil)
to_coord = to_facility.coord if to_facility.respond_to?(:coord) && to_coord.blank?
to_coord = GeoLocation.coord(to_lat, to_long) if to_coord.blank?

GeoLocation.distance(coord, to_coord)
end

def distance_in_meters(*params)
distance(*params).to_meters
def distance_in_meters(to_coord: nil, to_lat: nil, to_long: nil, to_facility: nil)
distance(to_coord: to_coord, to_lat: to_lat, to_long: to_long, to_facility: to_facility).to_meters
end

def distance_in_kms(*params)
distance(*params).to_kilometers
def distance_in_kms(to_coord: nil, to_lat: nil, to_long: nil, to_facility: nil)
distance(to_coord: to_coord, to_lat: to_lat, to_long: to_long, to_facility: to_facility).to_kilometers
end

private
Expand All @@ -144,4 +140,11 @@ def clean_data
# handles discard
self.discard_reason = :none if undiscarded?
end

def distance(to_coord: nil, to_lat: nil, to_long: nil, to_facility: nil)
to_coord = to_facility.coord if to_facility.respond_to?(:coord) && to_coord.blank?
to_coord = GeoLocation.coord(to_lat, to_long) if to_coord.blank?

GeoLocation.distance(coord, to_coord) # .to_kilometers
end
end
Loading