AI Support is a Rails application for managing customer support tickets. Customers can create tickets and add replies; each customer message is processed asynchronously by an OpenAI-powered support agent. Ticket history is sent to the agent on the first message, and later messages continue the same OpenAI response conversation.
- Create and view support tickets.
- Set ticket status (
open,in_progress,waiting_for_customer, orresolved) and priority (low,medium,high, orurgent). - Add customer replies while a ticket is not resolved.
- Process support messages through Solid Queue.
- Store AI replies and OpenAI response IDs so later replies can continue the conversation.
- Broadcast new messages to the ticket view with Turbo Streams.
The current application uses a demo customer account. ApplicationController selects the first user in the database, or creates Demo Customer (demo@example.com) when no user exists. There is no authentication flow yet.
- Ruby 3.4.9
- PostgreSQL 9.5 or newer
- Bundler
- An OpenAI API key
The application uses Rails 8.1, Puma, PostgreSQL, import maps, Hotwire, Solid Cache, Solid Queue, and Solid Cable. Foreman is installed automatically by bin/dev when it is not already available.
-
Install PostgreSQL and make sure the local server is running.
-
Set the OpenAI API key:
export OPENAI_KEY="your-openai-api-key"
OPENAI_KEYis required when the AI client is initialized. For local development, it can also be loaded throughdotenv-railsfrom a local.envfile. Do not commit that file. -
Install dependencies and prepare the databases:
bin/setup --skip-server
This installs Ruby dependencies and prepares the primary, queue, and cable databases. To recreate the databases and seed them again, run
bin/setup --reset --skip-server. -
Start the development application:
bin/dev
Visit http://localhost:3000. The development process runs the Rails web server and the Solid Queue worker defined in
Procfile.dev.
The seed data creates a demo customer and an example high-priority ticket:
bin/rails db:seed- A customer creates a ticket or posts a reply.
- Rails enqueues
ProcessSupportMessageJob. - The job locks the ticket, prevents concurrent processing, and marks it
in_progress. Ai::SupportAgentcalls the OpenAI Responses API usinggpt-4.1-mini.- The assistant response is saved as a message and linked to the customer message that produced it.
- The ticket changes to
waiting_for_customer.
Customer messages are processed in creation order. A ticket lock prevents concurrent jobs from processing the same ticket, and a message with an existing assistant reply is skipped so duplicate job execution does not create another reply.
Timeout, connection, and server failures are retried up to three attempts. If all attempts are exhausted, the job logs the failure, records an application message, and reopens the ticket. Non-retriable OpenAI and API request errors are handled the same way immediately. Other processing failures, including failures after an OpenAI response or while saving the assistant message, reopen the ticket and propagate the error for job monitoring.
# Start web and background-job processes
bin/dev
# Run the full RSpec suite
bundle exec rspec
# Run one spec file
bundle exec rspec spec/jobs/process_support_message_job_spec.rb
# Run Rails security and dependency checks
bin/brakeman --no-pager
bin/bundler-audit
bin/importmap audit
# Check Ruby style
bin/rubocop
# Open the Rails console
bin/rails consoleThe Solid Queue dashboard is available at http://localhost:3000/jobs in development.
/- ticket list/tickets/new- create a ticket/tickets/:id- view a ticket and its messages/up- Rails health check/jobs- Solid Queue dashboard in development
RSpec uses the ai_support_test PostgreSQL database. To run tests locally, ensure PostgreSQL is running and execute:
RAILS_ENV=test bundle exec rspecThe CI workflow runs Brakeman, Bundler Audit, Importmap Audit, and RuboCop, and runs the RSpec suite against PostgreSQL.
The included Dockerfile builds a production image for Ruby 3.4.9 and exposes port 80. It expects a production database password through AI_SUPPORT_DATABASE_PASSWORD and a Rails master key at runtime.
Build and run the image manually:
docker build -t ai_support .
docker run --rm -p 80:80 \
-e RAILS_MASTER_KEY="your-rails-master-key" \
-e AI_SUPPORT_DATABASE_PASSWORD="your-database-password" \
-e OPENAI_KEY="your-openai-api-key" \
ai_supportFor production deployments, the repository is configured for Kamal. Configure the production database, Rails credentials, and environment variables before deploying.