Files
sure/Gemfile.lock
MkDev11 6f8858b1a6 feat/Add AI-Powered Bank Statement Import (step 1, PDF import & analysis) (#808)
* feat: Add PDF import with AI-powered document analysis

This enhances the import functionality to support PDF files with AI-powered
document analysis. When a PDF is uploaded, it is processed by AI to:
- Identify the document type (bank statement, credit card statement, etc.)
- Generate a summary of the document contents
- Extract key metadata (institution, dates, balances, transaction count)

After processing, an email is sent to the user asking for next steps.

Key changes:
- Add PdfImport model for handling PDF document imports
- Add Provider::Openai::PdfProcessor for AI document analysis
- Add ProcessPdfJob for async PDF processing
- Add PdfImportMailer for user notification emails
- Update imports controller to detect and handle PDF uploads
- Add PDF import option to the new import page
- Add i18n translations for all new strings
- Add comprehensive tests for the new functionality

* Add bank statement import with AI extraction

- Create ImportBankStatement assistant function for MCP
- Add BankStatementExtractor with chunked processing for small context windows
- Register function in assistant configurable
- Make PdfImport#pdf_file_content public for extractor access
- Increase OpenAI request timeout to 600s for slow local models
- Increase DB connection pool to 20 for concurrent operations

Tested with M-Pesa bank statement via remote Ollama (qwen3:8b):
- Successfully extracted 18 transactions
- Generated CSV and created TransactionImport
- Works with 3000 char chunks for small context windows

* Add pdf-reader gem dependency

The BankStatementExtractor uses PDF::Reader to parse bank statement
PDFs, but the gem was not properly declared in the Gemfile. This would
cause NameError in production when processing bank statements.

Added pdf-reader ~> 2.12 to Gemfile dependencies.

* Fix transaction deduplication to preserve legitimate duplicates

The previous deduplication logic removed ALL duplicate transactions based
on [date, amount, name], which would drop legitimate same-day duplicates
like multiple ATM withdrawals or card authorizations.

Changed to only deduplicate transactions that appear in consecutive chunks
(chunking artifacts) while preserving all legitimate duplicates within the
same chunk or non-adjacent chunks.

* Refactor bank statement extraction to use public provider method

Address code review feedback:
- Add public extract_bank_statement method to Provider::Openai
- Remove direct access to private client via send(:client)
- Update ImportBankStatement to use new public method
- Add require 'set' to BankStatementExtractor
- Remove PII-sensitive content from error logs
- Add defensive check for nil response.error
- Handle oversized PDF pages in chunking logic
- Remove unused process_native and process_generic methods
- Update email copy to reflect feature availability
- Add guard for nil document_type in email template
- Document pdf-reader gem rationale in Gemfile

Tested with both OpenAI (gpt-4o) and Ollama (qwen3:8b):
- OpenAI: 49 transactions extracted in 30s
- Ollama: 40 transactions extracted in 368s
- All encapsulation and error handling working correctly

* Update schema.rb with ai_summary and document_type columns

* Address PR #808 review comments

- Rename :csv_file to :import_file across controllers/views/tests
- Add PDF test fixture (sample_bank_statement.pdf)
- Add supports_pdf_processing? method for graceful degradation
- Revert unrelated database.yml pool change (600->3)
- Remove month_start_day schema bleed from other PR
- Fix PdfProcessor: use .strip instead of .strip_heredoc
- Add server-side PDF magic byte validation
- Conditionally show PDF import option when AI provider available
- Fix ProcessPdfJob: sanitize errors, handle update failure
- Move pdf_file attachment from Import to PdfImport
- Document deduplication logic limitations
- Fix ImportBankStatement: catch specific exceptions only
- Remove unnecessary require 'set'
- Remove dead json_schema method from PdfProcessor
- Reduce default OpenAI timeout from 600s to 60s
- Fix nil guard in text mailer template
- Add require 'csv' to ImportBankStatement
- Remove Gemfile pdf-reader comment

* Fix RuboCop indentation in ProcessPdfJob

* Refactor PDF import check to use model predicate method

Replace is_a?(PdfImport) type check with requires_csv_workflow? predicate
that leverages STI inheritance for cleaner controller logic.

* Fix missing 'unknown' locale key and schema version mismatch

- Add 'unknown: Unknown Document' to document_types locale
- Fix schema version to match latest migration (2026_01_24_180211)

* Document OPENAI_REQUEST_TIMEOUT env variable

Added to .env.local.example and docs/hosting/ai.md

* Rename ALLOWED_MIME_TYPES to ALLOWED_CSV_MIME_TYPES for clarity

* Add comment explaining requires_csv_workflow? predicate

* Remove redundant required_column_keys from PdfImport

Base class already returns [] by default

* Add ENV toggle to disable PDF processing for non-vision endpoints

OPENAI_SUPPORTS_PDF_PROCESSING=false can be used for OpenAI-compatible
endpoints (e.g., Ollama) that don't support vision/PDF processing.

* Wire up transaction extraction for PDF bank statements

- Add extracted_data JSONB column to imports
- Add extract_transactions method to PdfImport
- Call extraction in ProcessPdfJob for bank statements
- Store transactions in extracted_data for later review

* Fix ProcessPdfJob retry logic, sanitize and localize errors

- Allow retries after partial success (classification ok, extraction failed)
- Log sanitized error message instead of raw message to avoid data leakage
- Use i18n for user-facing error messages

* Add vision-capable model validation for PDF processing

* Fix drag-and-drop test to use correct field name csv_file

* Schema bleedover from another branch

* Fix drag-drop import form field name to match controller

* Add vision capability guard to process_pdf method

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: mkdev11 <jaysmth689+github@users.noreply.github.com>
Co-authored-by: Juan José Mata <jjmata@jjmata.com>
2026-01-30 20:44:25 +01:00

885 lines
21 KiB
Plaintext

GEM
remote: https://rubygems.org/
specs:
Ascii85 (2.0.1)
aasm (5.5.1)
concurrent-ruby (~> 1.0)
actioncable (7.2.2.2)
actionpack (= 7.2.2.2)
activesupport (= 7.2.2.2)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (7.2.2.2)
actionpack (= 7.2.2.2)
activejob (= 7.2.2.2)
activerecord (= 7.2.2.2)
activestorage (= 7.2.2.2)
activesupport (= 7.2.2.2)
mail (>= 2.8.0)
actionmailer (7.2.2.2)
actionpack (= 7.2.2.2)
actionview (= 7.2.2.2)
activejob (= 7.2.2.2)
activesupport (= 7.2.2.2)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (7.2.2.2)
actionview (= 7.2.2.2)
activesupport (= 7.2.2.2)
nokogiri (>= 1.8.5)
racc
rack (>= 2.2.4, < 3.2)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (7.2.2.2)
actionpack (= 7.2.2.2)
activerecord (= 7.2.2.2)
activestorage (= 7.2.2.2)
activesupport (= 7.2.2.2)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (7.2.2.2)
activesupport (= 7.2.2.2)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (7.2.2.2)
activesupport (= 7.2.2.2)
globalid (>= 0.3.6)
activemodel (7.2.2.2)
activesupport (= 7.2.2.2)
activerecord (7.2.2.2)
activemodel (= 7.2.2.2)
activesupport (= 7.2.2.2)
timeout (>= 0.4.0)
activerecord-import (2.2.0)
activerecord (>= 4.2)
activestorage (7.2.2.2)
actionpack (= 7.2.2.2)
activejob (= 7.2.2.2)
activerecord (= 7.2.2.2)
activesupport (= 7.2.2.2)
marcel (~> 1.0)
activesupport (7.2.2.2)
base64
benchmark (>= 0.3)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
aes_key_wrap (1.1.0)
afm (1.0.0)
after_commit_everywhere (1.6.0)
activerecord (>= 4.2)
activesupport
ast (2.4.3)
attr_required (1.0.2)
aws-eventstream (1.4.0)
aws-partitions (1.1196.0)
aws-sdk-core (3.240.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
bigdecimal
jmespath (~> 1, >= 1.6.1)
logger
aws-sdk-kms (1.118.0)
aws-sdk-core (~> 3, >= 3.239.1)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.208.0)
aws-sdk-core (~> 3, >= 3.234.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.12.1)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.3.0)
bcrypt (3.1.20)
benchmark (0.4.1)
benchmark-ips (2.14.0)
better_html (2.1.1)
actionview (>= 6.0)
activesupport (>= 6.0)
ast (~> 2.0)
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.3.1)
bindata (2.5.1)
bindex (0.8.1)
bootsnap (1.18.6)
msgpack (~> 1.2)
brakeman (7.1.2)
racc
builder (3.3.0)
capybara (3.40.0)
addressable
matrix
mini_mime (>= 0.1.3)
nokogiri (~> 1.11)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
childprocess (5.1.0)
logger (~> 1.5)
chunky_png (1.4.0)
climate_control (1.2.0)
concurrent-ruby (1.3.5)
connection_pool (2.5.3)
countries (8.0.3)
unaccent (~> 0.3)
crack (1.0.0)
bigdecimal
rexml
crass (1.0.6)
cronex (0.15.0)
tzinfo
unicode (>= 0.4.4.5)
css_parser (1.21.1)
addressable
csv (3.3.5)
date (3.4.1)
debug (1.11.0)
irb (~> 1.10)
reline (>= 0.3.8)
derailed_benchmarks (2.2.1)
base64
benchmark-ips (~> 2)
bigdecimal
drb
get_process_mem
heapy (~> 0)
logger
memory_profiler (>= 0, < 2)
mini_histogram (>= 0.3.0)
mutex_m
ostruct
rack (>= 1)
rack-test
rake (> 10, < 14)
ruby-statistics (>= 4.0.1)
ruby2_keywords
thor (>= 0.19, < 2)
diff-lcs (1.6.2)
docile (1.4.1)
doorkeeper (5.8.2)
railties (>= 5)
dotenv (3.1.8)
dotenv-rails (3.1.8)
dotenv (= 3.1.8)
railties (>= 6.1)
drb (2.2.3)
ed25519 (1.4.0)
email_validator (2.2.4)
activemodel
erb (5.0.1)
erb_lint (0.9.0)
activesupport
better_html (>= 2.0.1)
parser (>= 2.7.1.4)
rainbow
rubocop (>= 1)
smart_properties
erubi (1.13.1)
et-orbi (1.2.11)
tzinfo
event_stream_parser (1.0.0)
faker (3.5.2)
i18n (>= 1.8.11, < 2)
faraday (2.13.2)
faraday-net_http (>= 2.0, < 3.5)
json
logger
faraday-follow_redirects (0.3.0)
faraday (>= 1, < 3)
faraday-multipart (1.1.1)
multipart-post (~> 2.0)
faraday-net_http (3.4.1)
net-http (>= 0.5.0)
faraday-retry (2.3.2)
faraday (~> 2.0)
ffi (1.17.2-aarch64-linux-gnu)
ffi (1.17.2-aarch64-linux-musl)
ffi (1.17.2-arm-linux-gnu)
ffi (1.17.2-arm-linux-musl)
ffi (1.17.2-arm64-darwin)
ffi (1.17.2-x86_64-darwin)
ffi (1.17.2-x86_64-linux-gnu)
ffi (1.17.2-x86_64-linux-musl)
flipper (1.3.6)
concurrent-ruby (< 2)
flipper-active_record (1.3.6)
activerecord (>= 4.2, < 9)
flipper (~> 1.3.6)
foreman (0.88.1)
fugit (1.11.1)
et-orbi (~> 1, >= 1.2.11)
raabro (~> 1.4)
get_process_mem (1.0.0)
bigdecimal (>= 2.0)
ffi (~> 1.0)
globalid (1.2.1)
activesupport (>= 6.1)
hashdiff (1.2.0)
hashery (2.1.2)
hashie (5.0.0)
heapy (0.2.0)
thor
highline (3.1.2)
reline
hotwire-livereload (2.0.0)
actioncable (>= 7.0.0)
listen (>= 3.0.0)
railties (>= 7.0.0)
hotwire_combobox (0.4.0)
platform_agent (>= 1.0.1)
rails (>= 7.0.7.2)
stimulus-rails (>= 1.2)
turbo-rails (>= 1.2)
htmlbeautifier (1.4.3)
htmlentities (4.3.4)
httparty (0.24.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
i18n-tasks (1.0.15)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
erubi
highline (>= 2.0.0)
i18n
parser (>= 3.2.2.1)
rails-i18n
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.8, >= 1.8.1)
terminal-table (>= 1.5.1)
image_processing (1.14.0)
mini_magick (>= 4.9.5, < 6)
ruby-vips (>= 2.0.17, < 3)
importmap-rails (2.1.0)
actionpack (>= 6.0.0)
activesupport (>= 6.0.0)
railties (>= 6.0.0)
inline_svg (1.10.0)
activesupport (>= 3.0)
nokogiri (>= 1.6)
io-console (0.8.0)
irb (1.15.2)
pp (>= 0.6.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jbuilder (2.13.0)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
jmespath (1.6.2)
json (2.12.2)
json-jwt (1.16.7)
activesupport (>= 4.2)
aes_key_wrap
base64
bindata
faraday (~> 2.0)
faraday-follow_redirects
json-schema (5.2.2)
addressable (~> 2.8)
bigdecimal (~> 3.1)
jwt (2.10.2)
base64
langfuse-ruby (0.1.4)
concurrent-ruby (~> 1.0)
faraday (>= 1.8, < 3.0)
faraday-net_http (>= 1.0, < 4.0)
json (~> 2.0)
language_server-protocol (3.17.0.5)
launchy (3.1.1)
addressable (~> 2.8)
childprocess (~> 5.0)
logger (~> 1.6)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
lint_roller (1.1.0)
listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
logger (1.7.0)
logtail (0.1.17)
msgpack (~> 1.0)
logtail-rack (0.2.6)
logtail (~> 0.1)
rack (>= 1.2, < 4.0)
logtail-rails (0.2.10)
actionpack (>= 5.0.0)
activerecord (>= 5.0.0)
logtail (~> 0.1, >= 0.1.14)
logtail-rack (~> 0.1)
railties (>= 5.0.0)
loofah (2.24.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
lookbook (2.3.11)
activemodel
css_parser
htmlbeautifier (~> 1.3)
htmlentities (~> 4.3.4)
marcel (~> 1.0)
railties (>= 5.0)
redcarpet (~> 3.5)
rouge (>= 3.26, < 5.0)
view_component (>= 2.0)
yard (~> 0.9)
zeitwerk (~> 2.5)
lucide-rails (0.7.3)
railties (>= 4.1.0)
mail (2.8.1)
mini_mime (>= 0.1.1)
net-imap
net-pop
net-smtp
marcel (1.0.4)
matrix (0.4.2)
memory_profiler (1.1.0)
method_source (1.1.0)
mini_histogram (0.3.1)
mini_magick (5.2.0)
benchmark
logger
mini_mime (1.1.5)
minitest (5.25.5)
mocha (2.7.1)
ruby2_keywords (>= 0.0.5)
msgpack (1.8.0)
multi_xml (0.8.0)
bigdecimal (>= 3.1, < 5)
multipart-post (2.4.1)
mutex_m (0.3.0)
net-http (0.6.0)
uri
net-imap (0.5.8)
date
net-protocol
net-pop (0.1.2)
net-protocol
net-protocol (0.2.2)
timeout
net-smtp (0.5.1)
net-protocol
nio4r (2.7.4)
nokogiri (1.18.9-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.9-x86_64-linux-musl)
racc (~> 1.4)
oauth2 (2.0.18)
faraday (>= 0.17.3, < 4.0)
jwt (>= 1.0, < 4.0)
logger (~> 1.2)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
snaky_hash (~> 2.0, >= 2.0.3)
version_gem (~> 1.1, >= 1.1.9)
octokit (10.0.0)
faraday (>= 1, < 3)
sawyer (~> 0.9)
omniauth (2.1.3)
hashie (>= 3.4.6)
rack (>= 2.2.3)
rack-protection
omniauth-github (2.0.1)
omniauth (~> 2.0)
omniauth-oauth2 (~> 1.8)
omniauth-google-oauth2 (1.2.1)
jwt (>= 2.9.2)
oauth2 (~> 2.0)
omniauth (~> 2.0)
omniauth-oauth2 (~> 1.8)
omniauth-oauth2 (1.8.0)
oauth2 (>= 1.4, < 3)
omniauth (~> 2.0)
omniauth-rails_csrf_protection (1.0.2)
actionpack (>= 4.2)
omniauth (~> 2.0)
omniauth-saml (2.2.4)
omniauth (~> 2.1)
ruby-saml (~> 1.18)
omniauth_openid_connect (0.8.0)
omniauth (>= 1.9, < 3)
openid_connect (~> 2.2)
openid_connect (2.3.1)
activemodel
attr_required (>= 1.0.0)
email_validator
faraday (~> 2.0)
faraday-follow_redirects
json-jwt (>= 1.16)
mail
rack-oauth2 (~> 2.2)
swd (~> 2.0)
tzinfo
validate_url
webfinger (~> 2.0)
ostruct (0.6.2)
pagy (9.3.5)
parallel (1.27.0)
parser (3.3.8.0)
ast (~> 2.4.1)
racc
pdf-reader (2.15.1)
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
afm (>= 0.2.1, < 2)
hashery (~> 2.0)
ruby-rc4
ttfunk
pg (1.5.9)
plaid (41.0.0)
faraday (>= 1.0.1, < 3.0)
faraday-multipart (>= 1.0.1, < 2.0)
platform_agent (1.0.1)
activesupport (>= 5.2.0)
useragent (~> 0.16.3)
posthog-ruby (3.3.3)
concurrent-ruby (~> 1)
pp (0.6.2)
prettyprint
prettyprint (0.2.0)
prism (1.4.0)
propshaft (1.1.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
psych (5.2.6)
date
stringio
public_suffix (6.0.2)
puma (6.6.0)
nio4r (~> 2.0)
pundit (2.5.2)
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.8.1)
rack (3.1.18)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
rack-cors (3.0.0)
logger
rack (>= 3.0.14)
rack-mini-profiler (4.0.0)
rack (>= 1.2.0)
rack-oauth2 (2.2.1)
activesupport
attr_required
faraday (~> 2.0)
faraday-follow_redirects
json-jwt (>= 1.11.0)
rack (>= 2.1.0)
rack-protection (4.1.1)
base64 (>= 0.1.0)
logger (>= 1.6.0)
rack (>= 3.0.0, < 4)
rack-session (2.1.1)
base64 (>= 0.1.0)
rack (>= 3.0.0)
rack-test (2.2.0)
rack (>= 1.3)
rackup (2.2.1)
rack (>= 3)
rails (7.2.2.2)
actioncable (= 7.2.2.2)
actionmailbox (= 7.2.2.2)
actionmailer (= 7.2.2.2)
actionpack (= 7.2.2.2)
actiontext (= 7.2.2.2)
actionview (= 7.2.2.2)
activejob (= 7.2.2.2)
activemodel (= 7.2.2.2)
activerecord (= 7.2.2.2)
activestorage (= 7.2.2.2)
activesupport (= 7.2.2.2)
bundler (>= 1.15.0)
railties (= 7.2.2.2)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails-i18n (7.0.10)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
rails-settings-cached (2.9.6)
activerecord (>= 5.0.0)
railties (>= 5.0.0)
railties (7.2.2.2)
actionpack (= 7.2.2.2)
activesupport (= 7.2.2.2)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
thor (~> 1.0, >= 1.2.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.0)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rbs (3.9.4)
logger
rchardet (1.10.0)
rdoc (6.14.2)
erb
psych (>= 4.0.0)
redcarpet (3.6.1)
redis (5.4.0)
redis-client (>= 0.22.0)
redis-client (0.25.0)
connection_pool
regexp_parser (2.10.0)
reline (0.6.1)
io-console (~> 0.5)
rexml (3.4.2)
rotp (6.3.0)
rouge (4.5.2)
rqrcode (3.1.0)
chunky_png (~> 1.0)
rqrcode_core (~> 2.0)
rqrcode_core (2.0.0)
rspec-core (3.13.6)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (8.0.2)
actionpack (>= 7.2)
activesupport (>= 7.2)
railties (>= 7.2)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.6)
rswag-api (2.16.0)
activesupport (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rswag-specs (2.16.0)
activesupport (>= 5.2, < 8.1)
json-schema (>= 2.2, < 6.0)
railties (>= 5.2, < 8.1)
rspec-core (>= 2.14)
rswag-ui (2.16.0)
actionpack (>= 5.2, < 8.1)
railties (>= 5.2, < 8.1)
rubocop (1.76.1)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.45.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.45.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
rubocop-performance (1.25.0)
lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.38.0, < 2.0)
rubocop-rails (2.32.0)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.44.0, < 2.0)
rubocop-rails-omakase (1.1.0)
rubocop (>= 1.72)
rubocop-performance (>= 1.24)
rubocop-rails (>= 2.30)
ruby-lsp (0.24.1)
language_server-protocol (~> 3.17.0)
prism (>= 1.2, < 2.0)
rbs (>= 3, < 5)
sorbet-runtime (>= 0.5.10782)
ruby-lsp-rails (0.4.6)
ruby-lsp (>= 0.24.0, < 0.25.0)
ruby-openai (8.1.0)
event_stream_parser (>= 0.3.0, < 2.0.0)
faraday (>= 1)
faraday-multipart (>= 1)
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
ruby-saml (1.18.1)
nokogiri (>= 1.13.10)
rexml
ruby-statistics (4.1.0)
ruby-vips (2.2.4)
ffi (~> 1.12)
logger
ruby2_keywords (0.0.5)
rubyzip (2.4.1)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
securerandom (0.4.1)
selenium-webdriver (4.34.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
sentry-rails (5.26.0)
railties (>= 5.0)
sentry-ruby (~> 5.26.0)
sentry-ruby (5.26.0)
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
sentry-sidekiq (5.26.0)
sentry-ruby (~> 5.26.0)
sidekiq (>= 3.0)
sidekiq (8.0.5)
connection_pool (>= 2.5.0)
json (>= 2.9.0)
logger (>= 1.6.2)
rack (>= 3.1.0)
redis-client (>= 0.23.2)
sidekiq-cron (2.3.0)
cronex (>= 0.13.0)
fugit (~> 1.8, >= 1.11.1)
globalid (>= 1.0.1)
sidekiq (>= 6.5.0)
sidekiq-unique-jobs (8.0.11)
concurrent-ruby (~> 1.0, >= 1.0.5)
sidekiq (>= 7.0.0, < 9.0.0)
thor (>= 1.0, < 3.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.13.1)
simplecov_json_formatter (0.1.4)
skylight (6.0.4)
activesupport (>= 5.2.0)
smart_properties (1.17.0)
snaky_hash (2.0.3)
hashie (>= 0.1.0, < 6)
version_gem (>= 1.1.8, < 3)
snaptrade (2.0.156)
faraday (>= 1.0.1, < 3.0)
faraday-multipart (~> 1.0, >= 1.0.4)
sorbet-runtime (0.5.12163)
stackprof (0.2.27)
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.7)
stripe (15.3.0)
swd (2.0.3)
activesupport (>= 3)
attr_required (>= 0.0.5)
faraday (~> 2.0)
faraday-follow_redirects
tailwindcss-rails (4.2.3)
railties (>= 7.0.0)
tailwindcss-ruby (~> 4.0)
tailwindcss-ruby (4.1.8)
tailwindcss-ruby (4.1.8-aarch64-linux-gnu)
tailwindcss-ruby (4.1.8-aarch64-linux-musl)
tailwindcss-ruby (4.1.8-arm64-darwin)
tailwindcss-ruby (4.1.8-x86_64-darwin)
tailwindcss-ruby (4.1.8-x86_64-linux-gnu)
tailwindcss-ruby (4.1.8-x86_64-linux-musl)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
thor (1.4.0)
timeout (0.4.3)
ttfunk (1.8.0)
bigdecimal (~> 3.1)
turbo-rails (2.0.16)
actionpack (>= 7.1.0)
railties (>= 7.1.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unaccent (0.4.0)
unicode (0.4.4.5)
unicode-display_width (3.1.4)
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
uri (1.0.4)
useragent (0.16.11)
validate_url (1.0.15)
activemodel (>= 3.0.0)
public_suffix
vcr (6.3.1)
base64
vernier (1.8.0)
version_gem (1.1.9)
view_component (3.23.2)
activesupport (>= 5.2.0, < 8.1)
concurrent-ruby (~> 1)
method_source (~> 1.0)
web-console (4.2.1)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webfinger (2.1.3)
activesupport
faraday (~> 2.0)
faraday-follow_redirects
webmock (3.25.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
websocket (1.2.11)
websocket-driver (0.8.0)
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.37)
zeitwerk (2.7.3)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES
aasm
activerecord-import
after_commit_everywhere (~> 1.0)
aws-sdk-s3 (~> 1.208.0)
bcrypt (~> 3.1)
benchmark-ips
bootsnap
brakeman
capybara
climate_control
countries
csv
debug
derailed_benchmarks
doorkeeper
dotenv-rails
ed25519
erb_lint
faker
faraday
faraday-multipart
faraday-retry
flipper
flipper-active_record
foreman
hotwire-livereload
hotwire_combobox
httparty
i18n-tasks
image_processing (>= 1.2)
importmap-rails
inline_svg
jbuilder
jwt
langfuse-ruby (~> 0.1.4)
letter_opener
logtail-rails
lookbook (= 2.3.11)
lucide-rails
mocha
octokit
omniauth (~> 2.1)
omniauth-github
omniauth-google-oauth2
omniauth-rails_csrf_protection
omniauth-saml (~> 2.1)
omniauth_openid_connect
ostruct
pagy
pdf-reader (~> 2.12)
pg (~> 1.5)
plaid
posthog-ruby
propshaft
puma (>= 5.0)
pundit
rack-attack (~> 6.6)
rack-cors
rack-mini-profiler
rails (~> 7.2.2)
rails-settings-cached
rchardet
redcarpet
redis (~> 5.4)
rotp (~> 6.3)
rqrcode (~> 3.0)
rspec-rails
rswag-api
rswag-specs
rswag-ui
rubocop-rails-omakase
ruby-lsp-rails
ruby-openai
rubyzip (~> 2.3)
selenium-webdriver
sentry-rails
sentry-ruby
sentry-sidekiq
sidekiq
sidekiq-cron
sidekiq-unique-jobs
simplecov
skylight
snaptrade (~> 2.0)
stackprof
stimulus-rails
stripe
tailwindcss-rails
turbo-rails
tzinfo-data
vcr
vernier
view_component
web-console
webmock
RUBY VERSION
ruby 3.4.7p58
BUNDLED WITH
2.6.7