This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Ruby on Rails 8 application for a People Performance system - an enterprise HR performance evaluation platform. It manages employee evaluations, calibration sessions, and performance reviews across different organizational roles.
- Backend: Ruby on Rails 8.0.2, Ruby 3.2
- Frontend: Shakapacker (Webpack 5), Stimulus, React 18, CoreUI
- Database: SQLite (development), MySQL (production - see README)
- Authentication: Devise with OmniAuth OpenID Connect (SSO)
- Authorization: Pundit with role-based access
- Background Jobs: Sidekiq
- UI Components: CoreUI, DataTables (server-side), Selectize
- Testing: Minitest, Capybara, Selenium
- Code Quality: StandardRB (RuboCop), Ruby LSP
- Package Manager: pnpm for Node packages, Bundler for Ruby gems
# Full setup (installs dependencies, sets up database, loads fixtures, starts dev server)
bin/setup
# Or step by step:
bundle install
bin/pnpm install
bin/rails db:prepare
RAILS_ENV=development bin/rails db:fixtures:load
bin/dev# Start development server with webpack dev server
bin/dev
# Or separately:
bin/rails server
bin/shakapacker-dev-serverbin/rails db:migrate
bin/rails db:fixtures:load
bin/rails db:rollback STEP=1# Run all tests
bin/rails test
# Run specific test file
bin/rails test test/models/user_test.rb
# Run tests with database reset
bin/rails test:db
# System tests (Capybara)
bin/rails test:system# Lint and fix code
bin/rubocop -A
# Security scanning
bin/brakeman# Compile assets for production
bin/shakapacker
# Install JavaScript dependencies
bin/pnpm installThe application uses four main namespaces with dedicated base controllers for role-based access:
-
Admin (
app/controllers/admin/base_controller.rb):- Requires admin role via
require_admin! - Manages system-wide settings, templates, and configurations
- Requires admin role via
-
HR (
app/controllers/hr/base_controller.rb):- Requires HR staff via
require_hr_staff! - Manages evaluation processes, calibration sessions, and HR workflows
- Requires HR staff via
-
CP (Corp President) (
app/controllers/cp/base_controller.rb):- Requires corp president via
require_corp_president! - Executive-level oversight and approvals
- Requires corp president via
-
Staff (
app/controllers/staff/base_controller.rb):- Requires authenticated user via
require_user! - Employee self-assessment and review participation
- Requires authenticated user via
Routes are organized into separate files:
- Main routes:
config/routes.rb - Admin routes:
config/routes/admin.rb - HR routes:
config/routes/hr.rb - CP routes:
config/routes/cp.rb - Staff routes:
config/routes/staff.rb
Each namespace file uses draw :namespace to load route definitions.
-
User: Central user model with Devise authentication and role checks
- Role methods:
admin?,hr_staff?,corp_president?,secretary?,hr_bp? - Associated with roles, job roles, evaluation capabilities
- Role methods:
-
EvaluationUserCapability: Core model for performance evaluations
-
CalibrationSession: Calibration process management
-
JobRole: Employee job roles and capabilities
-
CompanyEvaluationTemplate: Evaluation framework templates
-
CalibrationSessionUser/Judge: Participants in calibration sessions
Shakapacker Packs (app/javascript/packs/):
application.js- Global utilities (LocalTime, Simplebar)stimulus.js- Registers Stimulus controllersdatatables.js- DataTables initializationmark-scores.js- React component for scoring interfacecalibration-panel.js- React component for calibration UIcalibration-table.js- React component for calibration table
Stimulus Controllers:
- Global controllers in
app/javascript/controllers/ - Lazy-loaded controllers in
app/javascript/lazy_controllers/for feature-specific functionality
React Components:
- Mounted by page-specific packs using React 18
createRoot - Target specific DOM IDs (e.g.,
staff-mark,calibration-panel) - Components live in
app/javascript/react/
CoreUI Integration:
- CoreUI Pro used for UI components, tooltips, and carousels
- Initialized in
packs/stimulus.js
Ruby Datatables in app/datatables/:
- Base class:
application_datatable.rb - Examples:
users_datatable.rb,capability_datatable.rb
Frontend:
- Stimulus controller in
lazy_controllers/datatables.js - Include
data-controller="datatables"in views - Pass configuration via data attributes
Jobs located in app/sidekiq/:
- Email reminders (self-assessment, manager scoring, HR review)
- WeChat notifications
- Data import jobs (evaluations, performance, calibration sessions)
- Archive and cleanup jobs
Jobs handle workflow automation and notifications across the evaluation lifecycle.
Authentication:
- Devise configured in
config/routes.rbwith custom controllers - OmniAuth OpenID Connect for SSO
- Global authentication via
before_action :authenticate_user!
Authorization (Pundit):
- Included in
application_controller.rb - Base policy:
app/policies/application_policy.rb - Domain-specific policies in
app/policies/ - Use
authorize(record)in member actions - Use
policy_scope(Model)in collection actions
import.rake- Import Excel files for evaluations, performance, and calibrationmaintain.rake- Data maintenance and cleanupedoc2.rake- EDOC2 document integration
Set hmr: true in config/shakapacker.yml for hot module replacement.
Install:
- Ruby LSP by Shopify
- VSCode rdbg Ruby Debugger by KoichiSasada
Ensure only one version of the debug gem is installed:
gem uninstall -i /opt/homebrew/Cellar/ruby/3.2.2/lib/ruby/gems/3.2.0 debug
gem install debug --defaultmysql -u root
DROP DATABASE thape_pp_dev;
CREATE DATABASE thape_pp_dev character set UTF8mb4 collate utf8mb4_0900_ai_ci;
\q
gunzip < mysql_pp_db.sql.gz | mysql -u root thape_pp_devguochunzhong@thape.com.cn / pp_rocks
The following Cursor rules define project conventions:
- Namespaced base controllers enforce role-based access
- Pundit policies define granular permissions
- Always call
authorizeand usepolicy_scope
- Follow namespaced controller organization
- Place frontend code in correct packs/controllers directories
- Use Stimulus for interactivity, React for complex components
- Include
stimulusanddatatablespacks on relevant pages - CoreUI for UI components
- Mount React components with specific DOM IDs
- Append packs using
append_javascript_pack_taghelper
- Server-side processing with AjaxDatatablesRails
- Define
view_columns,data, andget_raw_recordsin Ruby - Pass column configuration via data attributes
- Wire up with Stimulus controller
- Place new features in appropriate namespace
- Update corresponding route file
- Inherit from namespace base controller
- Tests use Minitest
- System tests with Capybara and Selenium
- Fixtures in
test/fixtures/ - Model tests in
test/models/ - Mailer tests in
test/mailers/ - Use
bin/rails test:dbto reset database before testing
config/shakapacker.yml- Shakapacker configurationconfig/webpack/webpack.config.js- Webpack customization.rubocop.yml- StandardRB configurationconfig/initializers/omniauth.rb- OpenID Connect settingsbin/dev- Development server startup scriptbin/setup- Project initialization
- Always include "stimulus" - With webpack 5, loading sequence matters
- Use namespaced controllers - Inherit role-based access control
- Pundit authorization - Authorize every action, scope collections
- Server-side DataTables - Handle large datasets efficiently
- React for complex UIs - Use for scoring interfaces and calibration panels
- Sidekiq for background work - Email, notifications, imports, cleanup