├── .ruby-version
├── backend
├── .env
├── lib
│ ├── tasks
│ │ ├── .keep
│ │ ├── clear_cache.rake
│ │ └── seed_test_data.rake
│ ├── assets
│ │ └── .keep
│ ├── GeoIP2-Country.mmdb
│ └── aws_s3_client_timecop.rb
├── storage
│ └── .keep
├── .env.test
├── .ruby-version
├── app
│ ├── assets
│ │ ├── images
│ │ │ ├── .keep
│ │ │ ├── favicon-dark.png
│ │ │ ├── favicon-light.png
│ │ │ ├── mailers
│ │ │ │ ├── alert.png
│ │ │ │ ├── check.png
│ │ │ │ ├── clock.png
│ │ │ │ ├── stat-dollar.png
│ │ │ │ └── check-circle-filled.png
│ │ │ ├── thumbnails
│ │ │ │ ├── file-text.svg
│ │ │ │ ├── bank-default.svg
│ │ │ │ ├── bank-added.svg
│ │ │ │ └── eth.svg
│ │ │ ├── logo-icon.svg
│ │ │ └── default-company-logo.svg
│ │ ├── config
│ │ │ └── manifest.js
│ │ └── fonts
│ │ │ ├── ABCWhyte-Bold.woff
│ │ │ ├── Caveat-Regular.ttf
│ │ │ ├── ABCWhyte-Medium.woff
│ │ │ ├── ABCWhyte-Regular.woff
│ │ │ └── EamesCenturyModern-Regular.woff
│ ├── models
│ │ ├── concerns
│ │ │ ├── .keep
│ │ │ └── invoice
│ │ │ │ └── status.rb
│ │ ├── company_contractor.rb
│ │ ├── payment_balance_transaction.rb
│ │ ├── consolidated_payment_balance_transaction.rb
│ │ ├── consolidated_invoices_invoice.rb
│ │ ├── document_signature.rb
│ │ ├── tos_agreement.rb
│ │ ├── expense_category.rb
│ │ ├── share_class.rb
│ │ ├── redis_key.rb
│ │ ├── application_record.rb
│ │ ├── company_lawyer.rb
│ │ ├── company_administrator.rb
│ │ ├── document_template.rb
│ │ └── equity_exercise_bank_account.rb
│ ├── channels
│ │ └── application_cable
│ │ │ ├── channel.rb
│ │ │ └── connection.rb
│ ├── views
│ │ ├── fields
│ │ │ └── stripe_payment_intent_id_field
│ │ │ │ ├── _show.html.erb
│ │ │ │ ├── _index.html.erb
│ │ │ │ └── _form.html.erb
│ │ ├── user_mailer
│ │ │ ├── otp_code.html.erb
│ │ │ └── tax_id_validation_success.html.erb
│ │ ├── company_worker_mailer
│ │ │ ├── invite_worker.html.erb
│ │ │ └── _tracked_time.html.erb
│ │ ├── layouts
│ │ │ └── pdf.html.erb
│ │ ├── templates
│ │ │ └── pdf.html.erb
│ │ ├── company_lawyer_mailer
│ │ │ └── invitation_instructions.html.erb
│ │ ├── company_administrator_mailer
│ │ │ └── invitation_instructions.html.erb
│ │ └── devise_mailer
│ │ │ ├── invitation_instructions.html.erb
│ │ │ └── email_changed.html.erb
│ ├── policies
│ │ ├── document_policy.rb
│ │ ├── settings
│ │ │ ├── equity_policy.rb
│ │ │ └── dividend_policy.rb
│ │ ├── company_lawyer_policy.rb
│ │ ├── convertible_security_policy.rb
│ │ ├── consolidated_invoice_policy.rb
│ │ ├── wallet_policy.rb
│ │ ├── option_pool_policy.rb
│ │ ├── company_investor_policy.rb
│ │ ├── stripe_microdeposit_verification_policy.rb
│ │ ├── tax_policy.rb
│ │ ├── company_policy.rb
│ │ ├── share_class_policy.rb
│ │ ├── dividend_policy.rb
│ │ ├── bank_account_policy.rb
│ │ ├── document_templates_policy.rb
│ │ ├── dividend_computation_policy.rb
│ │ └── dividend_round_policy.rb
│ ├── controllers
│ │ ├── internal
│ │ │ ├── base_controller.rb
│ │ │ ├── settings
│ │ │ │ ├── base_controller.rb
│ │ │ │ └── equity_controller.rb
│ │ │ ├── companies
│ │ │ │ ├── base_controller.rb
│ │ │ │ ├── switch_controller.rb
│ │ │ │ └── share_classes_controller.rb
│ │ │ └── current_users_controller.rb
│ │ ├── oauth_redirects_controller.rb
│ │ └── admin
│ │ │ └── consolidated_invoices_controller.rb
│ ├── sidekiq
│ │ ├── wise_balance_update_job.rb
│ │ ├── charge_consolidated_invoice_job.rb
│ │ ├── process_consolidated_payment_job.rb
│ │ ├── company_update_email_job.rb
│ │ ├── email_blast_job.rb
│ │ ├── process_equity_grant_scheduled_vesting_job.rb
│ │ ├── company_worker_tax_info_reminder_email_job.rb
│ │ ├── company_administrator_tax_form_review_email_job.rb
│ │ ├── user_tax_form_review_reminder_email_job.rb
│ │ └── process_scheduled_vesting_for_equity_grants_job.rb
│ ├── serializers
│ │ └── base_serializer.rb
│ ├── mailers
│ │ ├── company_contractor_mailer.rb
│ │ ├── admin_mailer.rb
│ │ └── devise_mailer.rb
│ ├── services
│ │ ├── default_invoice_date.rb
│ │ └── company_worker_reminder_email_service.rb
│ └── fields
│ │ └── stripe_payment_intent_id_field.rb
├── spec
│ ├── fixtures
│ │ └── files
│ │ │ ├── empty.pdf
│ │ │ ├── image.png
│ │ │ ├── sample.pdf
│ │ │ ├── sample.zip
│ │ │ ├── contract.pdf
│ │ │ ├── company-logo.png
│ │ │ └── test_shareholders_data.xlsx
│ ├── factories
│ │ ├── integrations.rb
│ │ ├── quickbooks_integrations.rb
│ │ ├── company_lawyers.rb
│ │ ├── sequences.rb
│ │ ├── expense_categories.rb
│ │ ├── investor_dividend_rounds.rb
│ │ ├── tos_agreements.rb
│ │ ├── wise_credentials.rb
│ │ ├── company_investors.rb
│ │ ├── vesting_events.rb
│ │ ├── invoice_line_items.rb
│ │ ├── share_classes.rb
│ │ ├── company_investor_entities.rb
│ │ ├── dividend_computations.rb
│ │ ├── payment_balance_transactions.rb
│ │ ├── company_administrators.rb
│ │ ├── company_updates.rb
│ │ ├── document_templates.rb
│ │ ├── consolidated_payment_balance_transactions.rb
│ │ ├── dividend_payments.rb
│ │ ├── payments.rb
│ │ ├── equity_grant_exercise_requests.rb
│ │ ├── tender_offer_bids.rb
│ │ ├── dividend_rounds.rb
│ │ ├── equity_buyback_payments.rb
│ │ ├── option_pools.rb
│ │ ├── consolidated_payments.rb
│ │ ├── invoice_approvals.rb
│ │ ├── equity_buyback_rounds.rb
│ │ ├── convertible_securities.rb
│ │ ├── wise_recipients.rb
│ │ └── invoice_expenses.rb
│ ├── models
│ │ ├── integration_record_spec.rb
│ │ ├── payment_balance_transaction_spec.rb
│ │ ├── consolidated_payment_balance_transaction_spec.rb
│ │ ├── consolidated_invoices_invoice_spec.rb
│ │ ├── document_signature_spec.rb
│ │ └── tos_agreement_spec.rb
│ ├── support
│ │ ├── factory_bot.rb
│ │ ├── shoulda_matchers.rb
│ │ ├── wise_form_label.rb
│ │ └── rich_text_editor_helpers.rb
│ └── shared_examples
│ │ └── internal
│ │ ├── base_controller_concern.rb
│ │ ├── settings_base_controller_concern.rb
│ │ └── companies_base_controller_concern.rb
├── .rspec
├── config
│ ├── initializers
│ │ ├── pagy.rb
│ │ ├── clearbit.rb
│ │ ├── premailer_rails.rb
│ │ ├── constants.rb
│ │ ├── stripe.rb
│ │ ├── redis.rb
│ │ ├── money.rb
│ │ ├── mail_interceptors.rb
│ │ ├── aws.rb
│ │ ├── sprockets.rb
│ │ ├── time_formats.rb
│ │ ├── openai.rb
│ │ ├── wise.rb
│ │ ├── sidekiq_cron.rb
│ │ ├── mailer.rb
│ │ ├── rspec_github_formatter_patch.rb
│ │ ├── country.rb
│ │ └── date_formats.rb
│ ├── data
│ │ ├── tax_forms
│ │ │ ├── W-9.pdf
│ │ │ ├── 1042-S.pdf
│ │ │ ├── W-8BEN.pdf
│ │ │ ├── 1099-DIV.pdf
│ │ │ ├── 1099-NEC.pdf
│ │ │ └── W-8BEN-E.pdf
│ │ └── seed_templates
│ │ │ └── gumroad
│ │ │ └── logo.png
│ ├── environment.rb
│ ├── boot.rb
│ ├── cable.yml
│ └── domain.rb
├── bin
│ ├── rake
│ └── rails
├── public
│ └── robots.txt
├── Procfile
├── db
│ └── migrate
│ │ ├── 20250527191928_remove_wallets.rb
│ │ ├── 20250729150349_drop_time_entries.rb
│ │ ├── 20220304091535_add_name_to_users.rb
│ │ ├── 20220321143517_add_state_to_users.rb
│ │ ├── 20230615170616_add_tax_id_to_users.rb
│ │ ├── 20220316142528_add_country_to_users.rb
│ │ ├── 20250814120058_add_text_to_documents.rb
│ │ ├── 20220318190841_add_notes_to_invoices.rb
│ │ ├── 20220327211055_add_invoices_paid_at.rb
│ │ ├── 20221018192554_add_signature_to_users.rb
│ │ ├── 20250804180733_drop_pg_search_documents.rb
│ │ ├── 20220617101855_add_notes_to_invoices_again.rb
│ │ ├── 20240525091757_add_external_id_to_user.rb
│ │ ├── 20230825153403_remove_signature_from_user.rb
│ │ ├── 20231102235007_add_tax_id_status_to_user.rb
│ │ ├── 20240419192020_add_json_data_to_contract.rb
│ │ ├── 20240807023147_add_template_to_documents.rb
│ │ ├── 20250413205549_drop_contractor_profiles_table.rb
│ │ ├── 20250612194925_drop_cap_table_uploads.rb
│ │ ├── 20220316203843_add_flags_to_users.rb
│ │ ├── 20220819151640_make_users_country_not_null.rb
│ │ ├── 20230208162210_change_company_name_not_null.rb
│ │ ├── 20230417230217_add_gumroad_user_id_to_user.rb
│ │ ├── 20230928160449_modify_equity_grants.rb
│ │ ├── 20240122114734_add_login_provider_to_user.rb
│ │ ├── 20240403180509_add_rejected_at_to_invoices.rb
│ │ ├── 20240516161055_add_external_id_to_invoice.rb
│ │ ├── 20240529183633_add_external_id_to_company.rb
│ │ ├── 20240813210321_rename_bid_to_tender_offer_bid.rb
│ │ ├── 20250210173437_add_accepted_at_to_invoices.rb
│ │ ├── 20250624011111_add_deleted_at_to_invoices.rb
│ │ ├── 20250821084120_add_external_id_to_dividend.rb
│ │ ├── 20230710194547_remove_sent_at_from_payments.rb
│ │ ├── 20231122104838_add_equity_grant_id_to_contract.rb
│ │ ├── 20240806153813_add_country_code_to_companies.rb
│ │ ├── 20240806153939_add_country_code_to_invoices.rb
│ │ ├── 20250131213058_make_invoice_date_non_null.rb
│ │ ├── 20220321160314_add_currency_to_wise_recipients.rb
│ │ ├── 20220926111014_add_flags_to_companies.rb
│ │ ├── 20230927203049_add_option_pool_id_to_equity_grant.rb
│ │ ├── 20231019113610_add_issued_at_to_equity_grant.rb
│ │ ├── 20231107082154_add_flags_to_contract.rb
│ │ ├── 20240408094042_add_share_class_id_to_option_pool.rb
│ │ ├── 20240520143716_add_external_id_to_company_role.rb
│ │ ├── 20241014130303_add_external_id_to_option_pool.rb
│ │ ├── 20251001000000_make_invoice_bill_from_nullable.rb
│ │ ├── 20220516181824_add_country_to_wise_recipients.rb
│ │ ├── 20220822145652_add_citizenship_country_to_users.rb
│ │ ├── 20230622105746_add_retained_reason_to_dividend.rb
│ │ ├── 20230830190727_add_deactivated_at_to_companies.rb
│ │ ├── 20240221165341_add_company_id_to_tax_documents.rb
│ │ ├── 20240627144227_remove_type_from_wise_recipients.rb
│ │ ├── 20240724211307_add_flexile_fee_cents_to_invoices.rb
│ │ ├── 20241017195326_add_external_id_to_equity_grants.rb
│ │ ├── 20250312125249_remove_login_provider_from_users.rb
│ │ ├── 20250427190328_remove_job_description_from_roles.rb
│ │ ├── 20250812115511_add_exercise_notice_to_companies.rb
│ │ ├── 20220617095825_rename_invoice_notes_to_description.rb
│ │ ├── 20220726184804_add_stripe_customer_id_to_company.rb
│ │ ├── 20230530151841_change_user_residence_country_null.rb
│ │ ├── 20230704213511_remove_column_tax_id_number_from_users.rb
│ │ ├── 20231122064335_add_flags_to_equity_grant.rb
│ │ ├── 20231215201313_add_company_contractor_id_to_invoice.rb
│ │ ├── 20240329190557_add_expense_account_id_to_roles.rb
│ │ ├── 20240425125538_add_registration_state_to_company.rb
│ │ ├── 20240614070227_add_flags_to_company_roles.rb
│ │ ├── 20240716113041_add_company_contractor_id_to_document.rb
│ │ ├── 20240717154622_add_flags_to_share_classes.rb
│ │ ├── 20240808224904_add_external_id_to_company_updates.rb
│ │ ├── 20241025143725_add_external_id_to_dividend_round.rb
│ │ ├── 20250211171339_add_parsed_data_to_cap_table_upload.rb
│ │ ├── 20250507191755_add_cancelled_at_to_equity_grants.rb
│ │ ├── 20250523221854_remove_inviting_company_flag_from_users.rb
│ │ ├── 20250808180255_drop_video_url_from_company_updates.rb
│ │ ├── 20251002213957_add_share_holding_id_to_documents.rb
│ │ ├── 20220325062313_add_wise_transfer_status_to_payments.rb
│ │ ├── 20220719193832_add_ended_at_to_company_contractors.rb
│ │ ├── 20230802012941_add_company_investor_id_to_equity_grant.rb
│ │ ├── 20230821173716_make_invoice_number_not_null.rb
│ │ ├── 20231020085415_set_not_null_equity_grant_issued_at.rb
│ │ ├── 20240119054544_make_option_holder_name_not_null.rb
│ │ ├── 20240119054552_make_share_holder_name_not_null.rb
│ │ ├── 20240119080713_add_google_uid_to_user.rb
│ │ ├── 20240222122846_change_tax_documents_company_id_null.rb
│ │ ├── 20240324155031_remove_role_from_company_contractors.rb
│ │ ├── 20240517155916_add_external_id_to_company_investor.rb
│ │ ├── 20240801232907_remove_expense_cards_stripe_card_id.rb
│ │ ├── 20241022162624_add_json_data_to_integration_records.rb
│ │ ├── 20241211063003_make_business_entity_nullable.rb
│ │ ├── 20220726191955_add_stripe_setup_intent_id_to_company.rb
│ │ ├── 20220822145401_rename_user_country_to_residence_country.rb
│ │ ├── 20230301092245_add_valuation_to_company.rb
│ │ ├── 20230710194540_remove_sent_at_from_dividend_payments.rb
│ │ ├── 20230726170448_add_deleted_at_to_integration_records.rb
│ │ ├── 20240104165356_remove_dividend_id_from_dividend_payment.rb
│ │ ├── 20240118054909_add_option_holder_name_to_equity_grant.rb
│ │ ├── 20240118091816_add_share_holder_name_to_share_holding.rb
│ │ ├── 20240325183046_add_user_compliance_info_id_to_dividends.rb
│ │ ├── 20240410132359_add_active_exercise_id_to_equity_grant.rb
│ │ ├── 20240517155548_add_external_id_to_company_contractor.rb
│ │ ├── 20240702112605_change_invoice_line_items_minutes_null.rb
│ │ ├── 20240728124807_add_external_id_to_contractor_profile.rb
│ │ ├── 20240827200022_add_flags_to_company_investor.rb
│ │ ├── 20250112153333_add_clerk_id_to_users.rb
│ │ ├── 20250213204744_remove_docuseal_enabled_from_companies.rb
│ │ ├── 20250809120029_remove_lawyers_enabled_from_companies.rb
│ │ ├── 20220318173243_add_invoice_number_to_invoices.rb
│ │ ├── 20231002194523_add_exercise_period_to_equity_grant.rb
│ │ ├── 20231003151308_require_post_exit_exercise_months.rb
│ │ ├── 20231023075447_add_equity_percentage_to_contractor.rb
│ │ ├── 20240116052217_add_cap_table_notes_to_company_investor.rb
│ │ ├── 20240430013158_add_upcoming_dividend_cents_to_company.rb
│ │ ├── 20240430180828_add_bank_account_last_four_to_companies.rb
│ │ ├── 20240613135555_add_qualified_amount_cents_to_dividends.rb
│ │ ├── 20240618190754_remove_company_id_from_wise_credentials.rb
│ │ ├── 20240815115056_add_share_class_to_tender_offer_bid.rb
│ │ ├── 20240912062106_add_board_approval_date_to_equity_grants.rb
│ │ ├── 20241002080830_remove_status_from_tender_offer.rb
│ │ ├── 20241025143731_add_external_id_to_dividend_computation.rb
│ │ ├── 20241218185011_rename_requires_new_contract.rb
│ │ ├── 20250926102109_add_deactivated_at_to_company_investors.rb
│ │ ├── 20221208170203_remove_date_and_amount_from_invoice_line_items.rb
│ │ ├── 20230622114205_add_tax_cents_to_dividend_payment.rb
│ │ ├── 20230622211033_add_tax_information_confirmed_at_to_users.rb
│ │ ├── 20231214115910_add_flags_to_company_contractor.rb
│ │ ├── 20240131125755_add_flags_to_integration_records.rb
│ │ ├── 20240304171724_drop_invoices_rejected_by_foreign_key.rb
│ │ ├── 20240403104337_add_company_id_to_equity_grant_exercise.rb
│ │ ├── 20240408151218_make_share_class_id_in_option_pool_not_null.rb
│ │ ├── 20240501152824_add_tax_id_status_to_user_compliance_infos.rb
│ │ ├── 20240924102124_add_accepted_price_cents_to_tender_offer.rb
│ │ ├── 20241004185712_add_company_investor_entity_to_equity_grant.rb
│ │ ├── 20250220114012_add_external_id_to_company_administrators.rb
│ │ ├── 20250313110411_remove_google_uid_from_users.rb
│ │ ├── 20250427193714_remove_financing_rounds.rb
│ │ ├── 20250818124600_add_investment_amount_cents_to_dividends.rb
│ │ ├── 20250818160000_add_finalized_at_to_dividend_computations.rb
│ │ ├── 20230610062422_change_number_of_shares_in_dividends_nullable.rb
│ │ ├── 20230721040505_add_implied_shares_to_convertible_security.rb
│ │ ├── 20230722214839_remove_name_from_convertible_security.rb
│ │ ├── 20231218192742_change_contractor_id_in_invoice_to_not_null.rb
│ │ ├── 20240419191945_add_share_holding_id_to_equity_grant_exercise.rb
│ │ ├── 20240606122427_remove_hourly_rate_in_usd_from_company_roles.rb
│ │ ├── 20240612155407_add_trial_pay_rate_usd_to_company_role_rate.rb
│ │ ├── 20240627213240_add_null_constraint_to_wise_recipients_user_id.rb
│ │ ├── 20240720112643_add_unique_index_to_company_contractor.rb
│ │ ├── 20241004185705_add_company_investor_entity_to_share_holding.rb
│ │ ├── 20250305115530_remove_one_off_payments_enabled_from_companies.rb
│ │ ├── 20250305194150_make_document_templates_company_id_nullable.rb
│ │ ├── 20250717153309_remove_company_updates_enabled_from_companies.rb
│ │ ├── 20230421235855_add_fully_diluted_shares_to_company.rb
│ │ ├── 20230908080531_add_transfer_fee_in_cents_to_dividend_payment.rb
│ │ ├── 20230921175216_add_invoice_payment_day_to_company.rb
│ │ ├── 20240104160158_make_dividend_id_in_dividend_payment_optional.rb
│ │ ├── 20240309143430_renamed_expired_shares_to_forfeited_shares.rb
│ │ ├── 20240409074554_add_expense_account_id_to_expense_categories.rb
│ │ ├── 20240509172630_add_originally_acquired_at_to_share_holding.rb
│ │ ├── 20240509200823_change_originally_acquired_at_to_not_null.rb
│ │ ├── 20240806153834_add_country_code_to_company_role_applications.rb
│ │ ├── 20250120204829_add_docuseal_enabled_to_companies.rb
│ │ ├── 20250131214834_make_invoice_line_item_pay_rate_nullable.rb
│ │ ├── 20250211224422_add_default_for_created_at.rb
│ │ ├── 20230508161126_add_total_shares_to_company_investors.rb
│ │ ├── 20231218210218_add_equity_grant_id_to_invoices.rb
│ │ ├── 20231229212535_remove_timezone_from_company_role_applications.rb
│ │ ├── 20240303002827_remove_default_from_company_brand_color.rb
│ │ ├── 20240323160300_make_company_contractors_company_role_not_null.rb
│ │ ├── 20240409131626_remove_share_price_in_cents_from_share_holding.rb
│ │ ├── 20240717033757_add_total_options_to_company_investor.rb
│ │ ├── 20240720112907_add_unique_index_to_company_administrator.rb
│ │ ├── 20241004200317_remove_share_holding_from_equity_grant_exercises.rb
│ │ ├── 20221107184210_add_deleted_at_to_wise_recipients.rb
│ │ ├── 20230623143258_add_total_transaction_cents_to_dividend_payments.rb
│ │ ├── 20230623201300_add_net_amount_in_cents_to_dividend_payments.rb
│ │ ├── 20230627170019_add_wise_credential_id_to_dividend_payments.rb
│ │ ├── 20230716195817_add_invoice_number_to_consolidated_invoices.rb
│ │ ├── 20230802225255_remove_company_contractor_id_from_equity_grant.rb
│ │ ├── 20240115225636_add_status_to_company_role_applications.rb
│ │ ├── 20240430013312_add_upcoming_dividend_cents_to_company_investor.rb
│ │ ├── 20240612170817_change_dividend_payments_wise_credential_id_null.rb
│ │ ├── 20240722142141_change_dividends_issuance_date_to_not_null.rb
│ │ ├── 20240910205946_add_accepted_shares_to_tender_offer_bid.rb
│ │ ├── 20250128120046_remove_show_contractor_list_to_contractors.rb
│ │ ├── 20250303114213_remove_smart_invoice_default_date_from_companies.rb
│ │ ├── 20250623190844_remove_irs_tax_forms_flag_from_companies.rb
│ │ ├── 20220826042227_remove_amount_cents_from_consolidated_payment.rb
│ │ ├── 20221115210350_add_status_to_consolidated_invoices.rb
│ │ ├── 20230615094632_rename_external_id_to_integration_external_id.rb
│ │ ├── 20230722230044_make_convertible_investment_id_not_nullable.rb
│ │ ├── 20240604172723_add_pay_rate_type_to_company_contractors.rb
│ │ ├── 20240628164156_remove_invoice_payment_day_from_companies.rb
│ │ ├── 20240321213527_deprecate_equity_percentage_in_contractor.rb
│ │ ├── 20240613135649_add_dividends_issuance_date_to_dividend_computations.rb
│ │ ├── 20240625121057_add_bank_account_last_four_to_consolidated_payments.rb
│ │ ├── 20240722142226_change_qualified_amount_cents_in_dividends_to_not_null.rb
│ │ ├── 20240728154101_change_expense_cards_spending_limit_cents_null.rb
│ │ ├── 20240809124553_change_company_role_applications_country_code_null.rb
│ │ ├── 20250205172308_add_one_off_payments_enabled_to_companies.rb
│ │ ├── 20250416022423_change_board_approval_date_to_nullable_in_equity_grants.rb
│ │ ├── 20220603205157_add_business_name_to_user.rb
│ │ ├── 20230623195626_add_withholding_percentage_to_dividend_payments.rb
│ │ ├── 20230802182954_modify_equity_grant.rb
│ │ ├── 20240430013353_add_upcoming_dividend_cents_to_convertible_investment.rb
│ │ ├── 20240708055148_remove_exercise_price_cents_from_equity_grant_exercise.rb
│ │ ├── 20240813024505_remove_title_uniqueness_from_company_updates.rb
│ │ ├── 20250219170411_add_null_constraint_to_invoices_total_amount_in_usd_cents.rb
│ │ ├── 20250220081442_add_board_member_to_company_administrators.rb
│ │ ├── 20250729150347_drop_user_leads_table.rb
│ │ ├── 20230623084959_add_minimum_dividend_payment_in_cents_to_user.rb
│ │ ├── 20230721035245_add_convertible_investment_id_to_convertible_security.rb
│ │ ├── 20231026102739_add_share_prices_to_company.rb
│ │ ├── 20231204140935_add_tax_id_and_phone_number_to_companies.rb
│ │ ├── 20250807142705_remove_is_gumroad_from_companies.rb
│ │ ├── 20220511113507_create_user_leads.rb
│ │ ├── 20221128185429_add_wise_credential_id_to_wise_recipients.rb
│ │ ├── 20240410053921_add_default_option_expiry_months_to_option_pool.rb
│ │ ├── 20240417105511_add_equity_exercise_bank_account_id_to_equity_grant_exercise.rb
│ │ ├── 20240722142255_change_qualified_dividend_amount_usd_to_not_null.rb
│ │ ├── 20240806153641_add_country_code_columns_to_users.rb
│ │ ├── 20240813024554_add_period_to_company_updates.rb
│ │ ├── 20241230172408_drop_has_confirmed_personal_details_from_users.rb
│ │ ├── 20250618194445_add_signed_release_at_to_dividends.rb
│ │ ├── 20250717153308_change_quantity_to_decimal_in_invoice_line_items.rb
│ │ ├── 20250731200856_remove_cap_table_notes.rb
│ │ ├── 20240528130134_rename_hourly_rate_in_usd_to_pay_rate_usd_for_invoice_line_items.rb
│ │ ├── 20240711182941_add_expense_card_spending_limit_cents_to_company_roles.rb
│ │ ├── 20240919123940_modify_equity_buyback.rb
│ │ ├── 20220317195636_add_first_and_last_name_to_users.rb
│ │ ├── 20240419232352_remove_deprecated_equity_percentage_from_company_contractor.rb
│ │ ├── 20240522184215_remove_board_consents_and_members.rb
│ │ ├── 20240531115549_rename_hourly_rate_in_usd_to_pay_rate_usd_for_company_contractors.rb
│ │ ├── 20221129152334_add_type_to_wise_recipients.rb
│ │ ├── 20230209173916_add_required_invoice_approval_count_to_company.rb
│ │ ├── 20250210172646_add_min_and_max_equity_to_invoices.rb
│ │ ├── 20250211171942_add_external_id_to_cap_table_upload.rb
│ │ ├── 20250818155953_add_investment_amount_cents_to_dividend_computation_outputs.rb
│ │ ├── 20220322155454_add_columns_to_payments.rb
│ │ ├── 20220613190459_add_data_columns_to_invoices.rb
│ │ ├── 20221026144909_add_wise_credentials_to_company.rb
│ │ ├── 20230105174308_add_consolidated_records_null_constraints.rb
│ │ ├── 20240301145208_add_rejection_attributes_to_invoices.rb
│ │ ├── 20240731144904_rename_service_fee_cents_to_flexile_fee_cents.rb
│ │ ├── 20250527225258_add_contract_signed_elsewhere_to_company_contractors.rb
│ │ ├── 20250822115115_remove_docuseal_submission_id_from_documents.rb
│ │ ├── 20220613200226_make_invoice_data_required.rb
│ │ ├── 20230721020124_add_actively_hiring_to_company_roles.rb
│ │ ├── 20240613135554_add_qualified_dividend_amount_usd_to_dividend_computation_outputs.rb
│ │ ├── 20240928172317_add_external_id_to_document_signatures.rb
│ │ ├── 20250207000247_add_docuseal_submission_id_to_documents.rb
│ │ ├── 20220423124721_change_failed_invoice_status.rb
│ │ ├── 20231221203449_add_default_value_to_company_brand_color.rb
│ │ ├── 20220906045930_create_tos_agreements.rb
│ │ ├── 20230804222752_make_job_description_not_null.rb
│ │ ├── 20231019052937_add_vested_amount_in_cents_to_equity_grant.rb
│ │ ├── 20241223224206_change_lawyers_enabled_default_and_null.rb
│ │ ├── 20250506190655_remove_description_from_companies.rb
│ │ ├── 20250615204642_make_company_contractor_pay_rate_optional.rb
│ │ ├── 20250120172094_add_business_details_to_user_compliance_infos.rb
│ │ ├── 20250409162211_remove_deprecated_documents_columns.rb
│ │ ├── 20230414194814_create_balances.rb
│ │ ├── 20240806153642_add_country_code_columns_to_user_compliance_infos.rb
│ │ ├── 20241022131039_add_email_to_company_investor_entity.rb
│ │ ├── 20250620155105_remove_gumroad_user_id_from_dividend_payments.rb
│ │ ├── 20240820165305_change_user_to_signee_on_document_signatures.rb
│ │ ├── 20241114160214_add_feature_flags_to_companies.rb
│ │ ├── 20241224184310_change_confirmed_at_default_in_users.rb
│ │ ├── 20250204154018_add_invoice_type_to_invoices.rb
│ │ ├── 20221129145843_add_wise_credential_id_to_payments.rb
│ │ ├── 20230222154530_create_expense_categories.rb
│ │ ├── 20240605163943_make_hours_per_week_and_weeks_per_year_nullable.rb
│ │ ├── 20241014154903_remove_post_exit_exercise_months_from_equity_grant.rb
│ │ ├── 20241014155335_remove_post_exit_exercise_months_from_option_pool.rb
│ │ ├── 20250707204451_add_otp_fields_to_user.rb
│ │ ├── 20220225082613_create_payments.rb
│ │ ├── 20220613163112_change_invoice_status_sent_to_received.rb
│ │ ├── 20240814173723_modify_tender_offer.rb
│ │ ├── 20241120200341_add_unique_to_tender_offer_external_id.rb
│ │ ├── 20230803195331_create_wallets.rb
│ │ ├── 20231218165115_add_withheld_tax_columns_to_dividends.rb
│ │ ├── 20230816054447_create_dividend_computations.rb
│ │ ├── 20220201112650_create_company_administrators.rb
│ │ ├── 20240821080832_change_tender_offer_bid_number_of_shares_to_decimal.rb
│ │ ├── 20240912094702_add_option_grant_type_to_equity_grants.rb
│ │ ├── 20220316205140_add_legal_info_columns_to_users.rb
│ │ ├── 20220824085245_create_consolidated_invoices_invoice.rb
│ │ ├── 20220914082930_create_contracts.rb
│ │ ├── 20240103054838_create_dividends_dividend_payments.rb
│ │ ├── 20240717041849_add_fully_diluted_shares_to_company_investor.rb
│ │ ├── 20250605160217_remove_upcoming_dividend_cents.rb
│ │ ├── 20240401165753_track_wise_account_holder_name.rb
│ │ ├── 20250426024711_remove_trial_fields_from_database.rb
│ │ ├── 20230417195608_create_company_investors.rb
│ │ ├── 20230722214918_modify_convertible_investment.rb
│ │ ├── 20230824141215_change_dividend_computation_output.rb
│ │ ├── 20240604171705_create_company_role_rates.rb
│ │ ├── 20220317144815_create_table_wise_recipients.rb
│ │ ├── 20231005135221_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb
│ │ ├── 20240417102901_create_equity_exercise_bank_account.rb
│ │ ├── 20241123235931_add_not_null_to_company_lawyer_external_id.rb
│ │ ├── 20230816045639_create_share_classes.rb
│ │ ├── 20240906084605_create_equity_buybacks_equity_buyback_payments.rb
│ │ ├── 20250206171055_create_cap_table_uploads.rb
│ │ ├── 20241204162450_drop_pay_rate_usd_columns.rb
│ │ ├── 20250129155701_add_ready_for_payment_to_dividend_round.rb
│ │ ├── 20250812164518_remove_unused_company_update_columns.rb
│ │ ├── 20240927195452_add_update_attributes_to_tasks.rb
│ │ ├── 20220516185836_make_counry_code_not_null.rb
│ │ ├── 20240918102312_change_board_approval_date_in_equity_grants_to_not_null.rb
│ │ ├── 20250106170939_add_end_of_period_forfeiture_equity_grant_transaction_type.rb
│ │ ├── 20221220152354_create_integration_records.rb
│ │ ├── 20241122193554_remove_null_contraints_pay_rate_usd.rb
│ │ └── 20241129095301_add_cap_table_enabled_to_companies.rb
├── package.json
├── config.ru
├── Rakefile
└── test
│ └── mailers
│ └── previews
│ ├── company_update_mailer_preview.rb
│ ├── company_lawyer_mailer_preview.rb
│ └── company_administrator_mailer_preview.rb
├── scripts
└── create_pr.sh
├── .node-version
├── .slugignore
├── .cursorignore
├── frontend
├── .env.test
├── public
│ ├── icon-192.png
│ ├── icon-512.png
│ ├── apple-icon.png
│ ├── favicon-dark.png
│ ├── favicon-light.png
│ └── logo-icon.svg
├── app
│ ├── ABCWhyte-Bold.woff
│ ├── ABCWhyte-Medium.woff
│ ├── opengraph-image.png
│ ├── ABCWhyte-Regular.woff
│ ├── (dashboard)
│ │ ├── invoices
│ │ │ ├── new
│ │ │ │ └── page.tsx
│ │ │ └── [id]
│ │ │ │ └── edit
│ │ │ │ └── page.tsx
│ │ ├── support
│ │ │ ├── page.tsx
│ │ │ └── tools.ts
│ │ └── equity
│ │ │ └── tender_offers
│ │ │ └── index.ts
│ ├── not-found.tsx
│ ├── dashboard
│ │ └── route.ts
│ ├── (marketing)
│ │ └── icon-diamond.svg
│ ├── api
│ │ └── auth
│ │ │ └── [...nextauth]
│ │ │ └── route.ts
│ ├── rails_routes
│ │ └── route.ts
│ └── manifest.json
├── utils
│ ├── legal.ts
│ ├── numbers.ts
│ ├── pluralize.ts
│ └── assert.ts
├── components
│ ├── Link.tsx
│ ├── ui
│ │ └── skeleton.tsx
│ ├── navigation
│ │ └── NavBadge.tsx
│ ├── SkeletonList.tsx
│ └── Delta.tsx
├── drizzle.config.js
├── .gitignore
├── images
│ └── default-company-logo.svg
├── env
│ └── client.ts
└── trpc
│ └── routes
│ └── support.ts
├── .githooks
└── pre-commit
├── .cursorrules
├── .github
└── copilot-instructions.md
├── .prettierrc
├── e2e
├── samples
│ └── sample.zip
├── helpers
│ └── date.ts
└── tsconfig.json
├── .prettierignore
├── .puppeteerrc.cjs
├── Procfile.dev
├── Procfile.test
├── .gitattributes
├── bin
└── lint
└── patches
└── server-only.patch
/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.4.3
2 |
--------------------------------------------------------------------------------
/backend/.env:
--------------------------------------------------------------------------------
1 | ../.env
--------------------------------------------------------------------------------
/backend/lib/tasks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/backend/storage/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/scripts/create_pr.sh:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.node-version:
--------------------------------------------------------------------------------
1 | 22.14.0
2 |
--------------------------------------------------------------------------------
/.slugignore:
--------------------------------------------------------------------------------
1 | /test
2 | /spec
--------------------------------------------------------------------------------
/backend/lib/assets/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.cursorignore:
--------------------------------------------------------------------------------
1 | spec/fixtures/
2 |
--------------------------------------------------------------------------------
/backend/.env.test:
--------------------------------------------------------------------------------
1 | ../.env.test
--------------------------------------------------------------------------------
/backend/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.4.3
2 |
--------------------------------------------------------------------------------
/backend/app/assets/images/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/backend/app/models/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/frontend/.env.test:
--------------------------------------------------------------------------------
1 | ../.env.test
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/empty.pdf:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.githooks/pre-commit:
--------------------------------------------------------------------------------
1 | pnpm lint-staged
2 |
--------------------------------------------------------------------------------
/backend/spec/factories/integrations.rb:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/backend/spec/models/integration_record_spec.rb:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/backend/spec/factories/quickbooks_integrations.rb:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.cursorrules:
--------------------------------------------------------------------------------
1 | See CONTRIBUTING.md for development guidelines
2 |
--------------------------------------------------------------------------------
/.github/copilot-instructions.md:
--------------------------------------------------------------------------------
1 | See CONTRIBUTING.md for development guidelines
2 |
--------------------------------------------------------------------------------
/backend/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 | --tag ~skip
3 | --tag ~type:system
4 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 120,
3 | "plugins": ["prettier-plugin-tailwindcss"]
4 | }
5 |
--------------------------------------------------------------------------------
/e2e/samples/sample.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/e2e/samples/sample.zip
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | frontend/utils/routes.*
2 | backend
3 | vendor
4 | tmp
5 | frontend/.next
6 | .github
7 |
--------------------------------------------------------------------------------
/backend/config/initializers/pagy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "pagy/extras/size"
4 |
--------------------------------------------------------------------------------
/frontend/public/icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/public/icon-192.png
--------------------------------------------------------------------------------
/frontend/public/icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/public/icon-512.png
--------------------------------------------------------------------------------
/frontend/public/apple-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/public/apple-icon.png
--------------------------------------------------------------------------------
/backend/app/models/company_contractor.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | CompanyContractor = CompanyWorker
4 |
--------------------------------------------------------------------------------
/backend/lib/GeoIP2-Country.mmdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/lib/GeoIP2-Country.mmdb
--------------------------------------------------------------------------------
/frontend/app/ABCWhyte-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/app/ABCWhyte-Bold.woff
--------------------------------------------------------------------------------
/frontend/app/ABCWhyte-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/app/ABCWhyte-Medium.woff
--------------------------------------------------------------------------------
/frontend/app/opengraph-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/app/opengraph-image.png
--------------------------------------------------------------------------------
/frontend/public/favicon-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/public/favicon-dark.png
--------------------------------------------------------------------------------
/frontend/public/favicon-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/public/favicon-light.png
--------------------------------------------------------------------------------
/backend/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative "../config/boot"
3 | require "rake"
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/frontend/app/ABCWhyte-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/frontend/app/ABCWhyte-Regular.woff
--------------------------------------------------------------------------------
/backend/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_tree ../fonts
3 | //= link_tree ../stylesheets .css
--------------------------------------------------------------------------------
/backend/config/data/tax_forms/W-9.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/tax_forms/W-9.pdf
--------------------------------------------------------------------------------
/backend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 |
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/spec/fixtures/files/image.png
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/sample.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/spec/fixtures/files/sample.pdf
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/sample.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/spec/fixtures/files/sample.zip
--------------------------------------------------------------------------------
/.puppeteerrc.cjs:
--------------------------------------------------------------------------------
1 | const { join } = require("path");
2 |
3 | module.exports = { cacheDirectory: join(__dirname, ".puppeteer") };
4 |
--------------------------------------------------------------------------------
/backend/config/data/tax_forms/1042-S.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/tax_forms/1042-S.pdf
--------------------------------------------------------------------------------
/backend/config/data/tax_forms/W-8BEN.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/tax_forms/W-8BEN.pdf
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/contract.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/spec/fixtures/files/contract.pdf
--------------------------------------------------------------------------------
/frontend/utils/legal.ts:
--------------------------------------------------------------------------------
1 | export function getTinName(isBusiness: boolean) {
2 | return isBusiness ? "EIN" : "SSN or ITIN";
3 | }
4 |
--------------------------------------------------------------------------------
/backend/app/assets/fonts/ABCWhyte-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/fonts/ABCWhyte-Bold.woff
--------------------------------------------------------------------------------
/backend/app/assets/fonts/Caveat-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/fonts/Caveat-Regular.ttf
--------------------------------------------------------------------------------
/backend/app/assets/images/favicon-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/favicon-dark.png
--------------------------------------------------------------------------------
/backend/app/assets/images/favicon-light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/favicon-light.png
--------------------------------------------------------------------------------
/backend/app/assets/images/mailers/alert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/mailers/alert.png
--------------------------------------------------------------------------------
/backend/app/assets/images/mailers/check.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/mailers/check.png
--------------------------------------------------------------------------------
/backend/app/assets/images/mailers/clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/mailers/clock.png
--------------------------------------------------------------------------------
/backend/config/data/tax_forms/1099-DIV.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/tax_forms/1099-DIV.pdf
--------------------------------------------------------------------------------
/backend/config/data/tax_forms/1099-NEC.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/tax_forms/1099-NEC.pdf
--------------------------------------------------------------------------------
/backend/config/data/tax_forms/W-8BEN-E.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/tax_forms/W-8BEN-E.pdf
--------------------------------------------------------------------------------
/backend/config/initializers/clearbit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Clearbit.key = GlobalConfig.dig("clearbit", "api_key")
4 |
--------------------------------------------------------------------------------
/backend/config/initializers/premailer_rails.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Premailer::Rails.config[:remove_ids] = false
4 |
--------------------------------------------------------------------------------
/backend/app/assets/fonts/ABCWhyte-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/fonts/ABCWhyte-Medium.woff
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/company-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/spec/fixtures/files/company-logo.png
--------------------------------------------------------------------------------
/backend/app/assets/fonts/ABCWhyte-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/fonts/ABCWhyte-Regular.woff
--------------------------------------------------------------------------------
/backend/Procfile:
--------------------------------------------------------------------------------
1 | web: bundle exec puma -C config/puma.rb
2 | release: ./ci_scripts/release.sh
3 | sidekiq: bundle exec sidekiq -q default -q mailers
4 |
--------------------------------------------------------------------------------
/backend/app/assets/images/mailers/stat-dollar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/mailers/stat-dollar.png
--------------------------------------------------------------------------------
/backend/config/data/seed_templates/gumroad/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/config/data/seed_templates/gumroad/logo.png
--------------------------------------------------------------------------------
/backend/config/initializers/constants.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Application-wide constants
4 | SIGNUP_URL = "#{PROTOCOL}://#{DOMAIN}/signup"
5 |
--------------------------------------------------------------------------------
/backend/spec/fixtures/files/test_shareholders_data.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/spec/fixtures/files/test_shareholders_data.xlsx
--------------------------------------------------------------------------------
/backend/spec/support/factory_bot.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | RSpec.configure do |config|
4 | config.include FactoryBot::Syntax::Methods
5 | end
6 |
--------------------------------------------------------------------------------
/backend/app/assets/fonts/EamesCenturyModern-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/fonts/EamesCenturyModern-Regular.woff
--------------------------------------------------------------------------------
/backend/app/assets/images/mailers/check-circle-filled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/antiwork/flexile/HEAD/backend/app/assets/images/mailers/check-circle-filled.png
--------------------------------------------------------------------------------
/backend/config/initializers/stripe.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Stripe.api_key = GlobalConfig.get("STRIPE_SECRET_KEY")
4 | Stripe.api_version = "2024-04-10"
5 |
--------------------------------------------------------------------------------
/backend/db/migrate/20250527191928_remove_wallets.rb:
--------------------------------------------------------------------------------
1 | class RemoveWallets < ActiveRecord::Migration[8.0]
2 | def change
3 | drop_table :wallets
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/frontend/app/(dashboard)/invoices/new/page.tsx:
--------------------------------------------------------------------------------
1 | import Edit from "@/app/(dashboard)/invoices/Edit";
2 |
3 | export default function Page() {
4 | return
This code will expire in 10 minutes. If you didn't request this code, please ignore this email.
4 | -------------------------------------------------------------------------------- /backend/config/environment.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Load the Rails application. 4 | require_relative "application" 5 | 6 | # Initialize the Rails application. 7 | Rails.application.initialize! 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20220316203843_add_flags_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :users, :flags, :integer, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220819151640_make_users_country_not_null.rb: -------------------------------------------------------------------------------- 1 | class MakeUsersCountryNotNull < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :users, :country, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230208162210_change_company_name_not_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeCompanyNameNotNull < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :companies, :name, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230417230217_add_gumroad_user_id_to_user.rb: -------------------------------------------------------------------------------- 1 | class AddGumroadUserIdToUser < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :users, :gumroad_user_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230928160449_modify_equity_grants.rb: -------------------------------------------------------------------------------- 1 | class ModifyEquityGrants < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :equity_grants, :option_pool_id, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240122114734_add_login_provider_to_user.rb: -------------------------------------------------------------------------------- 1 | class AddLoginProviderToUser < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :users, :login_provider, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240403180509_add_rejected_at_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddRejectedAtToInvoices < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :invoices, :rejected_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240516161055_add_external_id_to_invoice.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToInvoice < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :invoices, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240529183633_add_external_id_to_company.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToCompany < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :companies, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240813210321_rename_bid_to_tender_offer_bid.rb: -------------------------------------------------------------------------------- 1 | class RenameBidToTenderOfferBid < ActiveRecord::Migration[7.1] 2 | def change 3 | rename_table :bids, :tender_offer_bids 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250210173437_add_accepted_at_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddAcceptedAtToInvoices < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :invoices, :accepted_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250624011111_add_deleted_at_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddDeletedAtToInvoices < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :invoices, :deleted_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250821084120_add_external_id_to_dividend.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToDividend < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :dividends, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/app/models/consolidated_invoices_invoice.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ConsolidatedInvoicesInvoice < ApplicationRecord 4 | belongs_to :consolidated_invoice 5 | belongs_to :invoice 6 | end 7 | -------------------------------------------------------------------------------- /backend/app/policies/consolidated_invoice_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ConsolidatedInvoicePolicy < ApplicationPolicy 4 | def index? 5 | company_administrator.present? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/policies/wallet_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class WalletPolicy < ApplicationPolicy 4 | def update? 5 | user.restricted_payout_country_resident? && user.investor? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20230710194547_remove_sent_at_from_payments.rb: -------------------------------------------------------------------------------- 1 | class RemoveSentAtFromPayments < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :payments, :sent_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231122104838_add_equity_grant_id_to_contract.rb: -------------------------------------------------------------------------------- 1 | class AddEquityGrantIdToContract < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :contracts, :equity_grant 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240806153813_add_country_code_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddCountryCodeToCompanies < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :companies, :country_code, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240806153939_add_country_code_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddCountryCodeToInvoices < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :invoices, :country_code, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250131213058_make_invoice_date_non_null.rb: -------------------------------------------------------------------------------- 1 | class MakeInvoiceDateNonNull < ActiveRecord::Migration[7.2] 2 | def change 3 | change_column_null :invoices, :invoice_date, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/factories/investor_dividend_rounds.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :investor_dividend_round do 5 | company_investor 6 | dividend_round 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/factories/tos_agreements.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :tos_agreement do 5 | user 6 | ip_address { Faker::Internet.ip_v4_address } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /Procfile.test: -------------------------------------------------------------------------------- 1 | web: cd backend && ./bin/rails s -p 3101 2 | sidekiq: cd backend && bundle exec sidekiq -q default -q mailers 3 | next: TZ=UTC [ -n "$CI" ] && pnpm next start frontend -p 3100 || pnpm next dev frontend -p 3100 4 | -------------------------------------------------------------------------------- /backend/app/controllers/internal/settings/base_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Internal::Settings::BaseController < Internal::BaseController 4 | before_action :authenticate_user_json! 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220321160314_add_currency_to_wise_recipients.rb: -------------------------------------------------------------------------------- 1 | class AddCurrencyToWiseRecipients < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :wise_recipients, :currency, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220926111014_add_flags_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToCompanies < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :companies, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230927203049_add_option_pool_id_to_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class AddOptionPoolIdToEquityGrant < ActiveRecord::Migration[7.0] 2 | def change 3 | add_reference :equity_grants, :option_pool 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231019113610_add_issued_at_to_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class AddIssuedAtToEquityGrant < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :equity_grants, :issued_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231107082154_add_flags_to_contract.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToContract < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :contracts, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240408094042_add_share_class_id_to_option_pool.rb: -------------------------------------------------------------------------------- 1 | class AddShareClassIdToOptionPool < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :option_pools, :share_class 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240520143716_add_external_id_to_company_role.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToCompanyRole < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_roles, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241014130303_add_external_id_to_option_pool.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToOptionPool < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :option_pools, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20251001000000_make_invoice_bill_from_nullable.rb: -------------------------------------------------------------------------------- 1 | class MakeInvoiceBillFromNullable < ActiveRecord::Migration[8.0] 2 | def change 3 | change_column_null :invoices, :bill_from, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rails", 3 | "packageManager": "pnpm@10.8.0", 4 | "dependencies": { 5 | "puppeteer": "^24.4.0" 6 | }, 7 | "pnpm": { 8 | "patchedDependencies": {} 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /backend/app/models/document_signature.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DocumentSignature < ApplicationRecord 4 | belongs_to :document 5 | belongs_to :user 6 | 7 | validates :title, presence: true 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/policies/option_pool_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class OptionPoolPolicy < ApplicationPolicy 4 | def create? 5 | company.equity_enabled? && company_administrator.present? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/views/company_worker_mailer/invite_worker.html.erb: -------------------------------------------------------------------------------- 1 | <%= render("shared/contractor_invitation", company: @company, user: @user, url: nil, 2 | contractor: @company_worker) %> 3 | -------------------------------------------------------------------------------- /backend/config/initializers/aws.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Aws.config.update( 4 | region: ENV["AWS_REGION"], 5 | credentials: Aws::Credentials.new(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"]) 6 | ) 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20220516181824_add_country_to_wise_recipients.rb: -------------------------------------------------------------------------------- 1 | class AddCountryToWiseRecipients < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :wise_recipients, :country_code, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220822145652_add_citizenship_country_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddCitizenshipCountryToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :users, :citizenship_country, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230622105746_add_retained_reason_to_dividend.rb: -------------------------------------------------------------------------------- 1 | class AddRetainedReasonToDividend < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :dividends, :retained_reason, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230830190727_add_deactivated_at_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddDeactivatedAtToCompanies < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :companies, :deactivated_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240221165341_add_company_id_to_tax_documents.rb: -------------------------------------------------------------------------------- 1 | class AddCompanyIdToTaxDocuments < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :tax_documents, :company, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240627144227_remove_type_from_wise_recipients.rb: -------------------------------------------------------------------------------- 1 | class RemoveTypeFromWiseRecipients < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_column :wise_recipients, :type, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240724211307_add_flexile_fee_cents_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddFlexileFeeCentsToInvoices < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :invoices, :flexile_fee_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241017195326_add_external_id_to_equity_grants.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToEquityGrants < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :equity_grants, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250312125249_remove_login_provider_from_users.rb: -------------------------------------------------------------------------------- 1 | class RemoveLoginProviderFromUsers < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :users, :login_provider, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250427190328_remove_job_description_from_roles.rb: -------------------------------------------------------------------------------- 1 | class RemoveJobDescriptionFromRoles < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :company_roles, :job_description 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250812115511_add_exercise_notice_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddExerciseNoticeToCompanies < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :companies, :exercise_notice, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/factories/wise_credentials.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :wise_credential do 5 | profile_id { WISE_PROFILE_ID } 6 | api_key { WISE_API_KEY } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/models/tos_agreement.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class TosAgreement < ApplicationRecord 4 | belongs_to :user 5 | 6 | validates :user_id, presence: true 7 | validates :ip_address, presence: true 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/policies/company_investor_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyInvestorPolicy < ApplicationPolicy 4 | def show? 5 | company_administrator.present? || company_lawyer.present? 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20220617095825_rename_invoice_notes_to_description.rb: -------------------------------------------------------------------------------- 1 | class RenameInvoiceNotesToDescription < ActiveRecord::Migration[7.0] 2 | def change 3 | rename_column :invoices, :notes, :description 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220726184804_add_stripe_customer_id_to_company.rb: -------------------------------------------------------------------------------- 1 | class AddStripeCustomerIdToCompany < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :companies, :stripe_customer_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230530151841_change_user_residence_country_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeUserResidenceCountryNull < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :users, :residence_country, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230704213511_remove_column_tax_id_number_from_users.rb: -------------------------------------------------------------------------------- 1 | class RemoveColumnTaxIdNumberFromUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :users, :tax_id_number, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231122064335_add_flags_to_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToEquityGrant < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :equity_grants, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231215201313_add_company_contractor_id_to_invoice.rb: -------------------------------------------------------------------------------- 1 | class AddCompanyContractorIdToInvoice < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :invoices, :company_contractor 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240329190557_add_expense_account_id_to_roles.rb: -------------------------------------------------------------------------------- 1 | class AddExpenseAccountIdToRoles < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_roles, :expense_account_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240425125538_add_registration_state_to_company.rb: -------------------------------------------------------------------------------- 1 | class AddRegistrationStateToCompany < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :companies, :registration_state, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240614070227_add_flags_to_company_roles.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToCompanyRoles < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_roles, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240716113041_add_company_contractor_id_to_document.rb: -------------------------------------------------------------------------------- 1 | class AddCompanyContractorIdToDocument < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :documents, :company_contractor 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240717154622_add_flags_to_share_classes.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToShareClasses < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :share_classes, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240808224904_add_external_id_to_company_updates.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToCompanyUpdates < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_updates, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241025143725_add_external_id_to_dividend_round.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToDividendRound < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :dividend_rounds, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250211171339_add_parsed_data_to_cap_table_upload.rb: -------------------------------------------------------------------------------- 1 | class AddParsedDataToCapTableUpload < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :cap_table_uploads, :parsed_data, :jsonb 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250507191755_add_cancelled_at_to_equity_grants.rb: -------------------------------------------------------------------------------- 1 | class AddCancelledAtToEquityGrants < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :equity_grants, :cancelled_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250523221854_remove_inviting_company_flag_from_users.rb: -------------------------------------------------------------------------------- 1 | class RemoveInvitingCompanyFlagFromUsers < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :users, :inviting_company 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250808180255_drop_video_url_from_company_updates.rb: -------------------------------------------------------------------------------- 1 | class DropVideoUrlFromCompanyUpdates < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :company_updates, :video_url, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20251002213957_add_share_holding_id_to_documents.rb: -------------------------------------------------------------------------------- 1 | class AddShareHoldingIdToDocuments < ActiveRecord::Migration[8.0] 2 | def change 3 | add_reference :documents, :share_holding, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/support/shoulda_matchers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Shoulda::Matchers.configure do |config| 4 | config.integrate do |with| 5 | with.test_framework :rspec 6 | with.library :rails 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/assets/images/thumbnails/file-text.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/views/fields/stripe_payment_intent_id_field/_form.html.erb: -------------------------------------------------------------------------------- 1 |Thank you for updating your tax information! Since your tax ID has now been validated, we're able to reduce your tax withholding to 0%.
3 | -------------------------------------------------------------------------------- /backend/config/initializers/sprockets.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Work around a segfault during assets compilation 4 | # https://github.com/sass/sassc-ruby/issues/207#issuecomment-674626874 5 | Sprockets.export_concurrent = false 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220318173243_add_invoice_number_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddInvoiceNumberToInvoices < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :invoices, :invoice_number, :string, null: false, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231002194523_add_exercise_period_to_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class AddExercisePeriodToEquityGrant < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :equity_grants, :post_exit_exercise_months, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231003151308_require_post_exit_exercise_months.rb: -------------------------------------------------------------------------------- 1 | class RequirePostExitExerciseMonths < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :equity_grants, :post_exit_exercise_months, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231023075447_add_equity_percentage_to_contractor.rb: -------------------------------------------------------------------------------- 1 | class AddEquityPercentageToContractor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_contractors, :equity_percentage, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240116052217_add_cap_table_notes_to_company_investor.rb: -------------------------------------------------------------------------------- 1 | class AddCapTableNotesToCompanyInvestor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_investors, :cap_table_notes, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240430013158_add_upcoming_dividend_cents_to_company.rb: -------------------------------------------------------------------------------- 1 | class AddUpcomingDividendCentsToCompany < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :companies, :upcoming_dividend_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240430180828_add_bank_account_last_four_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddBankAccountLastFourToCompanies < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :companies, :bank_account_last_four, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240613135555_add_qualified_amount_cents_to_dividends.rb: -------------------------------------------------------------------------------- 1 | class AddQualifiedAmountCentsToDividends < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :dividends, :qualified_amount_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240618190754_remove_company_id_from_wise_credentials.rb: -------------------------------------------------------------------------------- 1 | class RemoveCompanyIdFromWiseCredentials < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_reference :wise_credentials, :company, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240815115056_add_share_class_to_tender_offer_bid.rb: -------------------------------------------------------------------------------- 1 | class AddShareClassToTenderOfferBid < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :tender_offer_bids, :share_class, :string, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240912062106_add_board_approval_date_to_equity_grants.rb: -------------------------------------------------------------------------------- 1 | class AddBoardApprovalDateToEquityGrants < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :equity_grants, :board_approval_date, :date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241002080830_remove_status_from_tender_offer.rb: -------------------------------------------------------------------------------- 1 | class RemoveStatusFromTenderOffer < ActiveRecord::Migration[7.2] 2 | def change 3 | remove_column :tender_offers, :status, :integer, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241025143731_add_external_id_to_dividend_computation.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToDividendComputation < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :dividend_computations, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241218185011_rename_requires_new_contract.rb: -------------------------------------------------------------------------------- 1 | class RenameRequiresNewContract < ActiveRecord::Migration[7.2] 2 | def change 3 | rename_column :users, :requires_new_contract, :has_confirmed_personal_details 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250926102109_add_deactivated_at_to_company_investors.rb: -------------------------------------------------------------------------------- 1 | class AddDeactivatedAtToCompanyInvestors < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :company_investors, :deactivated_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/shared_examples/internal/base_controller_concern.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.shared_examples_for "inherits from Internal::BaseController" do 4 | it { is_expected.to be_a_kind_of(Internal::BaseController) } 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20221208170203_remove_date_and_amount_from_invoice_line_items.rb: -------------------------------------------------------------------------------- 1 | class RemoveDateAndAmountFromInvoiceLineItems < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_columns :invoice_line_items, :amount, :date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230622114205_add_tax_cents_to_dividend_payment.rb: -------------------------------------------------------------------------------- 1 | class AddTaxCentsToDividendPayment < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :dividend_payments, :withheld_tax_cents, :bigint, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230622211033_add_tax_information_confirmed_at_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddTaxInformationConfirmedAtToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :users, :tax_information_confirmed_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231214115910_add_flags_to_company_contractor.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToCompanyContractor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_contractors, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240131125755_add_flags_to_integration_records.rb: -------------------------------------------------------------------------------- 1 | class AddFlagsToIntegrationRecords < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :integration_records, :flags, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240304171724_drop_invoices_rejected_by_foreign_key.rb: -------------------------------------------------------------------------------- 1 | class DropInvoicesRejectedByForeignKey < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_foreign_key "invoices", "users", column: "rejected_by_id" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240403104337_add_company_id_to_equity_grant_exercise.rb: -------------------------------------------------------------------------------- 1 | class AddCompanyIdToEquityGrantExercise < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :equity_grant_exercises, :company, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240408151218_make_share_class_id_in_option_pool_not_null.rb: -------------------------------------------------------------------------------- 1 | class MakeShareClassIdInOptionPoolNotNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :option_pools, :share_class_id, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240501152824_add_tax_id_status_to_user_compliance_infos.rb: -------------------------------------------------------------------------------- 1 | class AddTaxIdStatusToUserComplianceInfos < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :user_compliance_infos, :tax_id_status, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240924102124_add_accepted_price_cents_to_tender_offer.rb: -------------------------------------------------------------------------------- 1 | class AddAcceptedPriceCentsToTenderOffer < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :tender_offers, :accepted_price_cents, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241004185712_add_company_investor_entity_to_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class AddCompanyInvestorEntityToEquityGrant < ActiveRecord::Migration[7.2] 2 | def change 3 | add_reference :equity_grants, :company_investor_entity 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250220114012_add_external_id_to_company_administrators.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToCompanyAdministrators < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :company_administrators, :external_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250313110411_remove_google_uid_from_users.rb: -------------------------------------------------------------------------------- 1 | class RemoveGoogleUidFromUsers < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_index :users, :google_uid 4 | remove_column :users, :google_uid, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20250427193714_remove_financing_rounds.rb: -------------------------------------------------------------------------------- 1 | class RemoveFinancingRounds < ActiveRecord::Migration[8.0] 2 | def change 3 | drop_table :financing_rounds 4 | remove_column :companies, :financing_rounds_enabled 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20250818124600_add_investment_amount_cents_to_dividends.rb: -------------------------------------------------------------------------------- 1 | class AddInvestmentAmountCentsToDividends < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :dividends, :investment_amount_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250818160000_add_finalized_at_to_dividend_computations.rb: -------------------------------------------------------------------------------- 1 | class AddFinalizedAtToDividendComputations < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :dividend_computations, :finalized_at, :datetime 4 | end 5 | end -------------------------------------------------------------------------------- /backend/lib/tasks/clear_cache.rake: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | desc "Empty `Rails.cache`" 4 | task clear_cache: :environment do 5 | Rails.cache.clear 6 | puts "Cache is cleared" 7 | end 8 | 9 | task "db:migrate" => :clear_cache 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20230610062422_change_number_of_shares_in_dividends_nullable.rb: -------------------------------------------------------------------------------- 1 | class ChangeNumberOfSharesInDividendsNullable < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :dividends, :number_of_shares, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230721040505_add_implied_shares_to_convertible_security.rb: -------------------------------------------------------------------------------- 1 | class AddImpliedSharesToConvertibleSecurity < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :convertible_securities, :implied_shares, :decimal 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230722214839_remove_name_from_convertible_security.rb: -------------------------------------------------------------------------------- 1 | class RemoveNameFromConvertibleSecurity < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :convertible_securities, :name, :string, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231218192742_change_contractor_id_in_invoice_to_not_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeContractorIdInInvoiceToNotNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :invoices, :company_contractor_id, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240419191945_add_share_holding_id_to_equity_grant_exercise.rb: -------------------------------------------------------------------------------- 1 | class AddShareHoldingIdToEquityGrantExercise < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :equity_grant_exercises, :share_holding 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240606122427_remove_hourly_rate_in_usd_from_company_roles.rb: -------------------------------------------------------------------------------- 1 | class RemoveHourlyRateInUsdFromCompanyRoles < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_column :company_roles, :hourly_rate_in_usd, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240612155407_add_trial_pay_rate_usd_to_company_role_rate.rb: -------------------------------------------------------------------------------- 1 | class AddTrialPayRateUsdToCompanyRoleRate < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_role_rates, :trial_pay_rate_usd, :integer 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240627213240_add_null_constraint_to_wise_recipients_user_id.rb: -------------------------------------------------------------------------------- 1 | class AddNullConstraintToWiseRecipientsUserId < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :wise_recipients, :user_id, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240720112643_add_unique_index_to_company_contractor.rb: -------------------------------------------------------------------------------- 1 | class AddUniqueIndexToCompanyContractor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_index :company_contractors, [:user_id, :company_id], unique: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241004185705_add_company_investor_entity_to_share_holding.rb: -------------------------------------------------------------------------------- 1 | class AddCompanyInvestorEntityToShareHolding < ActiveRecord::Migration[7.2] 2 | def change 3 | add_reference :share_holdings, :company_investor_entity 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250305115530_remove_one_off_payments_enabled_from_companies.rb: -------------------------------------------------------------------------------- 1 | class RemoveOneOffPaymentsEnabledFromCompanies < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :companies, :one_off_payments_enabled 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250305194150_make_document_templates_company_id_nullable.rb: -------------------------------------------------------------------------------- 1 | class MakeDocumentTemplatesCompanyIdNullable < ActiveRecord::Migration[8.0] 2 | def change 3 | change_column_null :document_templates, :company_id, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250717153309_remove_company_updates_enabled_from_companies.rb: -------------------------------------------------------------------------------- 1 | class RemoveCompanyUpdatesEnabledFromCompanies < ActiveRecord::Migration[7.2] 2 | def change 3 | remove_column :companies, :company_updates_enabled, :boolean 4 | end 5 | end -------------------------------------------------------------------------------- /backend/spec/models/payment_balance_transaction_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe PaymentBalanceTransaction do 4 | describe "associations" do 5 | it { is_expected.to belong_to(:payment).optional(false) } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /frontend/utils/pluralize.ts: -------------------------------------------------------------------------------- 1 | export const pluralize = (word: string, count: number, includeCount?: boolean) => { 2 | const pluralizedWord = count === 1 ? word : `${word}s`; 3 | return includeCount ? `${count} ${pluralizedWord}` : pluralizedWord; 4 | }; 5 | -------------------------------------------------------------------------------- /backend/app/controllers/internal/companies/base_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Internal::Companies::BaseController < Internal::BaseController 4 | before_action :authenticate_user_json! 5 | after_action :verify_authorized 6 | end 7 | -------------------------------------------------------------------------------- /backend/app/policies/tax_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class TaxPolicy < ApplicationPolicy 4 | def show? 5 | company_worker.present? || company_investor.present? 6 | end 7 | 8 | def update? 9 | show? 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20230421235855_add_fully_diluted_shares_to_company.rb: -------------------------------------------------------------------------------- 1 | class AddFullyDilutedSharesToCompany < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :companies, :fully_diluted_shares, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230908080531_add_transfer_fee_in_cents_to_dividend_payment.rb: -------------------------------------------------------------------------------- 1 | class AddTransferFeeInCentsToDividendPayment < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :dividend_payments, :transfer_fee_in_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230921175216_add_invoice_payment_day_to_company.rb: -------------------------------------------------------------------------------- 1 | class AddInvoicePaymentDayToCompany < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :companies, :invoice_payment_day, :integer, null: false, default: 7 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240104160158_make_dividend_id_in_dividend_payment_optional.rb: -------------------------------------------------------------------------------- 1 | class MakeDividendIdInDividendPaymentOptional < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :dividend_payments, :dividend_id, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240309143430_renamed_expired_shares_to_forfeited_shares.rb: -------------------------------------------------------------------------------- 1 | class RenamedExpiredSharesToForfeitedShares < ActiveRecord::Migration[7.1] 2 | def change 3 | rename_column :equity_grants, :expired_shares, :forfeited_shares 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240409074554_add_expense_account_id_to_expense_categories.rb: -------------------------------------------------------------------------------- 1 | class AddExpenseAccountIdToExpenseCategories < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :expense_categories, :expense_account_id, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240509172630_add_originally_acquired_at_to_share_holding.rb: -------------------------------------------------------------------------------- 1 | class AddOriginallyAcquiredAtToShareHolding < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :share_holdings, :originally_acquired_at, :datetime 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240509200823_change_originally_acquired_at_to_not_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeOriginallyAcquiredAtToNotNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :share_holdings, :originally_acquired_at, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240806153834_add_country_code_to_company_role_applications.rb: -------------------------------------------------------------------------------- 1 | class AddCountryCodeToCompanyRoleApplications < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_role_applications, :country_code, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250120204829_add_docuseal_enabled_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddDocusealEnabledToCompanies < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :companies, :docuseal_enabled, :boolean, default: false, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250131214834_make_invoice_line_item_pay_rate_nullable.rb: -------------------------------------------------------------------------------- 1 | class MakeInvoiceLineItemPayRateNullable < ActiveRecord::Migration[7.2] 2 | def change 3 | change_column_null :invoice_line_items, :pay_rate_in_subunits, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250211224422_add_default_for_created_at.rb: -------------------------------------------------------------------------------- 1 | class AddDefaultForCreatedAt < ActiveRecord::Migration[7.2] 2 | def change 3 | change_column_default :cap_table_uploads, :created_at, from: nil, to: -> { "CURRENT_TIMESTAMP" } 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/app/policies/company_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyPolicy < ApplicationPolicy 4 | def show? 5 | update? 6 | end 7 | 8 | def update? 9 | company_administrator.present? || record.nil? 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/policies/settings/dividend_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Settings::DividendPolicy < ApplicationPolicy 4 | def show? 5 | company_investor.present? 6 | end 7 | 8 | def update? 9 | show? 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/config/initializers/time_formats.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Time::DATE_FORMATS[:long_date] = "%B %-d, %Y" # Date with no zero-padding + Long Month name + Year 4 | Time::DATE_FORMATS[:us_date] = "%-m/%-d/%Y" # Month/Date/Year with no zero-padding 5 | -------------------------------------------------------------------------------- /backend/db/migrate/20230508161126_add_total_shares_to_company_investors.rb: -------------------------------------------------------------------------------- 1 | class AddTotalSharesToCompanyInvestors < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :company_investors, :total_shares, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20231218210218_add_equity_grant_id_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddEquityGrantIdToInvoices < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :invoices, :equity_grant_id, :bigint 4 | add_index :invoices, :equity_grant_id 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20231229212535_remove_timezone_from_company_role_applications.rb: -------------------------------------------------------------------------------- 1 | class RemoveTimezoneFromCompanyRoleApplications < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_column :company_role_applications, :timezone, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240303002827_remove_default_from_company_brand_color.rb: -------------------------------------------------------------------------------- 1 | class RemoveDefaultFromCompanyBrandColor < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column :companies, :brand_color, :string, default: nil, null: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240323160300_make_company_contractors_company_role_not_null.rb: -------------------------------------------------------------------------------- 1 | class MakeCompanyContractorsCompanyRoleNotNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :company_contractors, :company_role_id, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240409131626_remove_share_price_in_cents_from_share_holding.rb: -------------------------------------------------------------------------------- 1 | class RemoveSharePriceInCentsFromShareHolding < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_column :share_holdings, :share_price_in_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240717033757_add_total_options_to_company_investor.rb: -------------------------------------------------------------------------------- 1 | class AddTotalOptionsToCompanyInvestor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_investors, :total_options, :bigint, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240720112907_add_unique_index_to_company_administrator.rb: -------------------------------------------------------------------------------- 1 | class AddUniqueIndexToCompanyAdministrator < ActiveRecord::Migration[7.1] 2 | def change 3 | add_index :company_administrators, [:user_id, :company_id], unique: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20241004200317_remove_share_holding_from_equity_grant_exercises.rb: -------------------------------------------------------------------------------- 1 | class RemoveShareHoldingFromEquityGrantExercises < ActiveRecord::Migration[7.2] 2 | def change 3 | remove_reference :equity_grant_exercises, :share_holding 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/factories/vesting_events.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :vesting_event do 5 | association :equity_grant 6 | vesting_date { DateTime.current } 7 | vested_shares { 100 } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/config/initializers/openai.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | request_timeout_in_seconds = 3 4 | 5 | OpenAI.configure do |config| 6 | config.access_token = GlobalConfig.get("OPENAI_API_KEY") 7 | config.request_timeout = request_timeout_in_seconds 8 | end 9 | -------------------------------------------------------------------------------- /backend/config/initializers/wise.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | WISE_API_KEY = ENV["WISE_API_KEY"] 4 | WISE_PROFILE_ID = ENV["WISE_PROFILE_ID"] 5 | WISE_API_URL = Rails.env.production? ? "https://api.transferwise.com" : "https://api.sandbox.transferwise.tech" 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20221107184210_add_deleted_at_to_wise_recipients.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AddDeletedAtToWiseRecipients < ActiveRecord::Migration[7.0] 4 | def change 5 | add_column :wise_recipients, :deleted_at, :datetime 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20230623143258_add_total_transaction_cents_to_dividend_payments.rb: -------------------------------------------------------------------------------- 1 | class AddTotalTransactionCentsToDividendPayments < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :dividend_payments, :total_transaction_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230623201300_add_net_amount_in_cents_to_dividend_payments.rb: -------------------------------------------------------------------------------- 1 | class AddNetAmountInCentsToDividendPayments < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :dividend_payments, :net_amount_in_cents, :bigint, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230627170019_add_wise_credential_id_to_dividend_payments.rb: -------------------------------------------------------------------------------- 1 | class AddWiseCredentialIdToDividendPayments < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :dividend_payments, :wise_credential_id, :bigint, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230716195817_add_invoice_number_to_consolidated_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddInvoiceNumberToConsolidatedInvoices < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :consolidated_invoices, :invoice_number, :string, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230802225255_remove_company_contractor_id_from_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class RemoveCompanyContractorIdFromEquityGrant < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_reference :equity_grants, :company_contractor, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240115225636_add_status_to_company_role_applications.rb: -------------------------------------------------------------------------------- 1 | class AddStatusToCompanyRoleApplications < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_role_applications, :status, :integer, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240430013312_add_upcoming_dividend_cents_to_company_investor.rb: -------------------------------------------------------------------------------- 1 | class AddUpcomingDividendCentsToCompanyInvestor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_investors, :upcoming_dividend_cents, :bigint 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240612170817_change_dividend_payments_wise_credential_id_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeDividendPaymentsWiseCredentialIdNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :dividend_payments, :wise_credential_id, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240722142141_change_dividends_issuance_date_to_not_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeDividendsIssuanceDateToNotNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :dividend_computations, :dividends_issuance_date, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240910205946_add_accepted_shares_to_tender_offer_bid.rb: -------------------------------------------------------------------------------- 1 | class AddAcceptedSharesToTenderOfferBid < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :tender_offer_bids, :accepted_shares, :decimal, default: 0, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250128120046_remove_show_contractor_list_to_contractors.rb: -------------------------------------------------------------------------------- 1 | class RemoveShowContractorListToContractors < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :companies, :show_contractor_list_to_contractors, :boolean 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250303114213_remove_smart_invoice_default_date_from_companies.rb: -------------------------------------------------------------------------------- 1 | class RemoveSmartInvoiceDefaultDateFromCompanies < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :companies, :smart_invoice_default_date_enabled 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250623190844_remove_irs_tax_forms_flag_from_companies.rb: -------------------------------------------------------------------------------- 1 | class RemoveIrsTaxFormsFlagFromCompanies < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :companies, :irs_tax_forms, :boolean, default: false, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/support/wise_form_label.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module WiseFormLabel 4 | extend self 5 | 6 | def email = "Email" 7 | def date_of_birth = "Recipient's date of birth" 8 | def account_number = "IBAN / Account number" 9 | end 10 | -------------------------------------------------------------------------------- /frontend/drizzle.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "drizzle-kit"; 2 | export default defineConfig({ 3 | out: "./db", 4 | schema: "./db/schema.ts", 5 | dialect: "postgresql", 6 | dbCredentials: { 7 | url: process.env.DATABASE_URL, 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /backend/app/controllers/oauth_redirects_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class OauthRedirectsController < ApplicationController 4 | def show 5 | render inline: "", layout: "application", status: params.key?(:code) ? :ok : :bad_request 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/sidekiq/wise_balance_update_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class WiseBalanceUpdateJob 4 | include Sidekiq::Job 5 | sidekiq_options retry: 5 6 | 7 | def perform 8 | Wise::AccountBalance.refresh_flexile_balance 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20220826042227_remove_amount_cents_from_consolidated_payment.rb: -------------------------------------------------------------------------------- 1 | class RemoveAmountCentsFromConsolidatedPayment < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :consolidated_payments, :amount_cents, :bigint, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20221115210350_add_status_to_consolidated_invoices.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AddStatusToConsolidatedInvoices < ActiveRecord::Migration[7.0] 4 | def change 5 | add_column :consolidated_invoices, :status, :string 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20230615094632_rename_external_id_to_integration_external_id.rb: -------------------------------------------------------------------------------- 1 | class RenameExternalIdToIntegrationExternalId < ActiveRecord::Migration[7.0] 2 | def change 3 | rename_column :integration_records, :external_id, :integration_external_id 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20230722230044_make_convertible_investment_id_not_nullable.rb: -------------------------------------------------------------------------------- 1 | class MakeConvertibleInvestmentIdNotNullable < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :convertible_securities, :convertible_investment_id, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240604172723_add_pay_rate_type_to_company_contractors.rb: -------------------------------------------------------------------------------- 1 | class AddPayRateTypeToCompanyContractors < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_contractors, :pay_rate_type, :integer, null: false, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240628164156_remove_invoice_payment_day_from_companies.rb: -------------------------------------------------------------------------------- 1 | class RemoveInvoicePaymentDayFromCompanies < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_column :companies, :invoice_payment_day, :integer, default: 7, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/shared_examples/internal/settings_base_controller_concern.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.shared_examples_for "inherits from Internal::Settings::BaseController" do 4 | it { is_expected.to be_a_kind_of(Internal::Settings::BaseController) } 5 | end 6 | -------------------------------------------------------------------------------- /backend/app/models/expense_category.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ExpenseCategory < ApplicationRecord 4 | belongs_to :company 5 | has_many :invoice_expenses 6 | 7 | validates :name, presence: true 8 | validates :company, presence: true 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/policies/share_class_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ShareClassPolicy < ApplicationPolicy 4 | def index? 5 | return false unless company.equity_enabled? 6 | company_administrator.present? || company_lawyer.present? 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/config/boot.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 4 | 5 | require "bundler/setup" # Set up gems listed in the Gemfile. 6 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20240321213527_deprecate_equity_percentage_in_contractor.rb: -------------------------------------------------------------------------------- 1 | class DeprecateEquityPercentageInContractor < ActiveRecord::Migration[7.1] 2 | def change 3 | rename_column :company_contractors, :equity_percentage, :deprecated_equity_percentage 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240613135649_add_dividends_issuance_date_to_dividend_computations.rb: -------------------------------------------------------------------------------- 1 | class AddDividendsIssuanceDateToDividendComputations < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :dividend_computations, :dividends_issuance_date, :date 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240625121057_add_bank_account_last_four_to_consolidated_payments.rb: -------------------------------------------------------------------------------- 1 | class AddBankAccountLastFourToConsolidatedPayments < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :consolidated_payments, :bank_account_last_four, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240722142226_change_qualified_amount_cents_in_dividends_to_not_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeQualifiedAmountCentsInDividendsToNotNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :dividends, :qualified_amount_cents, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240728154101_change_expense_cards_spending_limit_cents_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeExpenseCardsSpendingLimitCentsNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :company_roles, :expense_card_spending_limit_cents, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240809124553_change_company_role_applications_country_code_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeCompanyRoleApplicationsCountryCodeNull < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :company_role_applications, :country_code, false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250205172308_add_one_off_payments_enabled_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddOneOffPaymentsEnabledToCompanies < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :companies, :one_off_payments_enabled, :boolean, default: false, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250416022423_change_board_approval_date_to_nullable_in_equity_grants.rb: -------------------------------------------------------------------------------- 1 | class ChangeBoardApprovalDateToNullableInEquityGrants < ActiveRecord::Migration[8.0] 2 | def change 3 | change_column_null :equity_grants, :board_approval_date, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/spec/shared_examples/internal/companies_base_controller_concern.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.shared_examples_for "inherits from Internal::Companies::BaseController" do 4 | it { is_expected.to be_a_kind_of(Internal::Companies::BaseController) } 5 | end 6 | -------------------------------------------------------------------------------- /frontend/app/dashboard/route.ts: -------------------------------------------------------------------------------- 1 | import { redirect } from "next/navigation"; 2 | import { getRedirectUrl } from "@/lib/getRedirectUrl"; 3 | 4 | export async function GET(req: Request) { 5 | const redirectUrl = await getRedirectUrl(req); 6 | return redirect(redirectUrl); 7 | } 8 | -------------------------------------------------------------------------------- /backend/app/serializers/base_serializer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class BaseSerializer 4 | attr_reader :object 5 | 6 | def initialize(object) 7 | @object = object 8 | end 9 | 10 | def attributes 11 | raise "Not implemented" 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/app/views/company_worker_mailer/_tracked_time.html.erb: -------------------------------------------------------------------------------- 1 |<%= @company.name %> has invited you to join their legal team on Flexile.
4 | 5 | <%= link_to "Accept invitation and set up account", @url, class: "button" %> 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20220322155454_add_columns_to_payments.rb: -------------------------------------------------------------------------------- 1 | class AddColumnsToPayments < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :payments, :processor_uuid, :string 4 | add_column :payments, :wise_quote_id, :string 5 | add_column :payments, :wise_transfer_id, :string 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20220613190459_add_data_columns_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddDataColumnsToInvoices < ActiveRecord::Migration[7.0] 2 | def change 3 | change_table :invoices, bulk: true do |t| 4 | t.date :due_on 5 | t.string :bill_from 6 | t.string :bill_to 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20221026144909_add_wise_credentials_to_company.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AddWiseCredentialsToCompany < ActiveRecord::Migration[7.0] 4 | def change 5 | add_column :companies, :wise_profile_id, :string 6 | add_column :companies, :wise_api_key, :string 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20230105174308_add_consolidated_records_null_constraints.rb: -------------------------------------------------------------------------------- 1 | class AddConsolidatedRecordsNullConstraints < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :consolidated_payments, :type, false 4 | change_column_null :consolidated_invoices, :status, false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20240301145208_add_rejection_attributes_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddRejectionAttributesToInvoices < ActiveRecord::Migration[7.1] 2 | def change 3 | add_reference :invoices, :rejected_by, foreign_key: { to_table: :users } 4 | add_column :invoices, :rejection_reason, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20240731144904_rename_service_fee_cents_to_flexile_fee_cents.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class RenameServiceFeeCentsToFlexileFeeCents < ActiveRecord::Migration[7.1] 4 | def change 5 | rename_column :consolidated_invoices, :service_fee_cents, :flexile_fee_cents 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20250527225258_add_contract_signed_elsewhere_to_company_contractors.rb: -------------------------------------------------------------------------------- 1 | class AddContractSignedElsewhereToCompanyContractors < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :company_contractors, :contract_signed_elsewhere, :boolean, default: false, null: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20250822115115_remove_docuseal_submission_id_from_documents.rb: -------------------------------------------------------------------------------- 1 | class RemoveDocusealSubmissionIdFromDocuments < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_index :documents, :docuseal_submission_id 4 | remove_column :documents, :docuseal_submission_id, :integer 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/spec/factories/dividend_computations.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :dividend_computation do 5 | company 6 | total_amount_in_usd { 1_000_000 } 7 | dividends_issuance_date { Time.current } 8 | return_of_capital { false } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/app/policies/dividend_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DividendPolicy < ApplicationPolicy 4 | def index? 5 | company_investor.present? 6 | end 7 | 8 | def show? 9 | index? && user.legal_name.present? 10 | end 11 | 12 | def sign? 13 | show? 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/db/migrate/20220613200226_make_invoice_data_required.rb: -------------------------------------------------------------------------------- 1 | class MakeInvoiceDataRequired < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :invoices, :due_on, false 4 | change_column_null :invoices, :bill_from, false 5 | change_column_null :invoices, :bill_to, false 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20230721020124_add_actively_hiring_to_company_roles.rb: -------------------------------------------------------------------------------- 1 | class AddActivelyHiringToCompanyRoles < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :company_roles, :actively_hiring 4 | add_column :company_roles, :actively_hiring, :boolean, null: false, default: false 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20240613135554_add_qualified_dividend_amount_usd_to_dividend_computation_outputs.rb: -------------------------------------------------------------------------------- 1 | class AddQualifiedDividendAmountUsdToDividendComputationOutputs < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :dividend_computation_outputs, :qualified_dividend_amount_usd, :decimal 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20240928172317_add_external_id_to_document_signatures.rb: -------------------------------------------------------------------------------- 1 | class AddExternalIdToDocumentSignatures < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :document_signatures, :external_id, :string, null: false 4 | add_index :document_signatures, :external_id, unique: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20250207000247_add_docuseal_submission_id_to_documents.rb: -------------------------------------------------------------------------------- 1 | class AddDocusealSubmissionIdToDocuments < ActiveRecord::Migration[7.2] 2 | def change 3 | change_table :documents do |t| 4 | t.integer :docuseal_submission_id 5 | t.index :docuseal_submission_id 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/factories/payment_balance_transactions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :payment_balance_transaction do 5 | company 6 | payment 7 | amount_cents { 1_200_00 } 8 | transaction_type { BalanceTransaction::PAYMENT_INITIATED } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /frontend/app/(marketing)/icon-diamond.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/components/navigation/NavBadge.tsx: -------------------------------------------------------------------------------- 1 | import { Badge } from "@/components/ui/badge"; 2 | 3 | export const NavBadge = ({ count }: { count: number }) => ( 4 |<%= @company.name %> has invited you to join their administrative team on Flexile.
4 | 5 | <%= link_to "Accept invitation and set up account", @url, class: "button" %> 6 | -------------------------------------------------------------------------------- /backend/config/initializers/sidekiq_cron.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Sidekiq.configure_server do |config| 4 | config.on(:startup) do 5 | sidekiq_schedule = YAML.load_file(Rails.root.join("config", "sidekiq_schedule.yml")) 6 | Sidekiq::Cron::Job.load_from_hash!(sidekiq_schedule, source: "schedule") 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20230414194814_create_balances.rb: -------------------------------------------------------------------------------- 1 | class CreateBalances < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :balances do |t| 4 | t.references :company, null: false, index: true 5 | t.bigint :amount_cents, null: false, default: 0 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20240806153642_add_country_code_columns_to_user_compliance_infos.rb: -------------------------------------------------------------------------------- 1 | class AddCountryCodeColumnsToUserComplianceInfos < ActiveRecord::Migration[7.1] 2 | def change 3 | change_table :user_compliance_infos do |t| 4 | t.string :country_code 5 | t.string :citizenship_country_code 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20241022131039_add_email_to_company_investor_entity.rb: -------------------------------------------------------------------------------- 1 | class AddEmailToCompanyInvestorEntity < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :company_investor_entities, :email, :string, null: false 4 | add_index :company_investor_entities, [:company_id, :email, :name], unique: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20250620155105_remove_gumroad_user_id_from_dividend_payments.rb: -------------------------------------------------------------------------------- 1 | class RemoveGumroadUserIdFromDividendPayments < ActiveRecord::Migration[7.0] 2 | def change 3 | if column_exists?(:dividend_payments, :gumroad_user_id) 4 | remove_column :dividend_payments, :gumroad_user_id, :string 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../frontend/tsconfig.json", 3 | "compilerOptions": { 4 | "types": ["node", "@playwright/test"], 5 | "baseUrl": ".", 6 | "paths": { 7 | "@test/*": ["./*"], 8 | "@/*": ["../frontend/*"] 9 | } 10 | }, 11 | "include": ["./**/*.ts", "../frontend/types/*.d.ts"] 12 | } 13 | -------------------------------------------------------------------------------- /backend/app/controllers/internal/companies/switch_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Internal::Companies::SwitchController < Internal::Companies::BaseController 4 | def create 5 | skip_authorization 6 | 7 | render json: UserPresenter.new(current_context: pundit_user).logged_in_user 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20240820165305_change_user_to_signee_on_document_signatures.rb: -------------------------------------------------------------------------------- 1 | class ChangeUserToSigneeOnDocumentSignatures < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_belongs_to :document_signatures, :user, null: false 4 | add_reference :document_signatures, :signable, null: false, polymorphic: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20241114160214_add_feature_flags_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddFeatureFlagsToCompanies < ActiveRecord::Migration[7.2] 2 | def change 3 | change_table :companies do |t| 4 | t.boolean :show_analytics_to_contractors, default: false 5 | t.boolean :company_updates_enabled, default: false 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20241224184310_change_confirmed_at_default_in_users.rb: -------------------------------------------------------------------------------- 1 | class ChangeConfirmedAtDefaultInUsers < ActiveRecord::Migration[7.2] 2 | def change 3 | change_column_default :users, :confirmed_at, from: nil, to: -> { 'CURRENT_TIMESTAMP' } 4 | change_column_null :users, :confirmed_at, false, -> { "created_at" } 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20250204154018_add_invoice_type_to_invoices.rb: -------------------------------------------------------------------------------- 1 | class AddInvoiceTypeToInvoices < ActiveRecord::Migration[7.2] 2 | def change 3 | create_enum :invoices_invoice_type, %w[services other] 4 | add_column :invoices, :invoice_type, :enum, enum_type: :invoices_invoice_type, null: false, default: "services" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/spec/factories/company_updates.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :company_update do 5 | company 6 | title do 7 | last_month = 1.month.ago 8 | "#{last_month.strftime('%B')} #{last_month.year}" 9 | end 10 | body { Faker::Lorem.paragraph } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/spec/factories/document_templates.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :document_template do 5 | company 6 | trait :exercise_notice do 7 | document_type { DocumentTemplate.document_types[:exercise_notice] } 8 | text { "I am exercising" } 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/views/devise_mailer/invitation_instructions.html.erb: -------------------------------------------------------------------------------- 1 | <% company = @resource.invited_by.company_administrators.first&.company %> 2 | <%= render("shared/contractor_invitation", company:, user: @resource, url: SIGNUP_URL, 3 | contractor: @resource.company_workers.find_by(company_id: company.id)) %> 4 | -------------------------------------------------------------------------------- /backend/db/migrate/20221129145843_add_wise_credential_id_to_payments.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AddWiseCredentialIdToPayments < ActiveRecord::Migration[7.0] 4 | def change 5 | add_reference :payments, :wise_credential, index: true 6 | add_reference :consolidated_payments, :wise_credential, index: true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20230222154530_create_expense_categories.rb: -------------------------------------------------------------------------------- 1 | class CreateExpenseCategories < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :expense_categories do |t| 4 | t.references :company, null: false, index: true 5 | t.string :name, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20240605163943_make_hours_per_week_and_weeks_per_year_nullable.rb: -------------------------------------------------------------------------------- 1 | class MakeHoursPerWeekAndWeeksPerYearNullable < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :company_role_applications, :hours_per_week, true 4 | change_column_null :company_role_applications, :weeks_per_year, true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20241014154903_remove_post_exit_exercise_months_from_equity_grant.rb: -------------------------------------------------------------------------------- 1 | class RemovePostExitExerciseMonthsFromEquityGrant < ActiveRecord::Migration[7.2] 2 | def up 3 | remove_column :equity_grants, :post_exit_exercise_months 4 | end 5 | 6 | def down 7 | raise ActiveRecord::IrreversibleMigration 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20241014155335_remove_post_exit_exercise_months_from_option_pool.rb: -------------------------------------------------------------------------------- 1 | class RemovePostExitExerciseMonthsFromOptionPool < ActiveRecord::Migration[7.2] 2 | def up 3 | remove_column :option_pools, :post_exit_exercise_months 4 | end 5 | 6 | def down 7 | raise ActiveRecord::IrreversibleMigration 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20250707204451_add_otp_fields_to_user.rb: -------------------------------------------------------------------------------- 1 | class AddOtpFieldsToUser < ActiveRecord::Migration[8.0] 2 | def change 3 | add_column :users, :otp_secret_key, :string 4 | add_column :users, :otp_failed_attempts_count, :integer, default: 0, null: false 5 | add_column :users, :otp_first_failed_at, :datetime 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20220225082613_create_payments.rb: -------------------------------------------------------------------------------- 1 | class CreatePayments < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :payments do |t| 4 | t.references :invoice, null: false, index: true 5 | t.datetime :sent_at 6 | t.string :status, null: false 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20220613163112_change_invoice_status_sent_to_received.rb: -------------------------------------------------------------------------------- 1 | class ChangeInvoiceStatusSentToReceived < ActiveRecord::Migration[7.0] 2 | def up 3 | Invoice.where(status: "sent").update_all(status: "received") 4 | end 5 | 6 | def down 7 | Invoice.where(status: "received").update_all(status: "sent") 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20240814173723_modify_tender_offer.rb: -------------------------------------------------------------------------------- 1 | class ModifyTenderOffer < ActiveRecord::Migration[7.1] 2 | def change 3 | change_column_null :tender_offers, :total_amount_in_cents, true 4 | change_column_null :tender_offers, :number_of_shares, true 5 | change_column_null :tender_offers, :number_of_shareholders, true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20241120200341_add_unique_to_tender_offer_external_id.rb: -------------------------------------------------------------------------------- 1 | class AddUniqueToTenderOfferExternalId < ActiveRecord::Migration[7.2] 2 | def change 3 | remove_index :tender_offers, :external_id 4 | add_index :tender_offers, :external_id, unique: true 5 | add_index :tender_offer_bids, :external_id, unique: true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/sidekiq/email_blast_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class EmailBlastJob 4 | include Sidekiq::Job 5 | 6 | def perform 7 | return unless Rails.env.production? 8 | 9 | CompanyAdministrator.find_each do |admin| 10 | CompanyMailer.email_blast(admin_id: admin.id).deliver_later 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/config/initializers/mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | case Rails.env 4 | when "test" 5 | Rails.application.config.action_mailer.delivery_method = :test 6 | when "development", "staging", "production" 7 | Rails.application.config.action_mailer.delivery_method = :resend 8 | Resend.api_key = ENV.fetch("RESEND_API_KEY") 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20230803195331_create_wallets.rb: -------------------------------------------------------------------------------- 1 | class CreateWallets < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :wallets do |t| 4 | t.references :user, null: false, index: true 5 | t.string :wallet_address, null: false 6 | t.datetime :deleted_at 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20231218165115_add_withheld_tax_columns_to_dividends.rb: -------------------------------------------------------------------------------- 1 | class AddWithheldTaxColumnsToDividends < ActiveRecord::Migration[7.1] 2 | def change 3 | change_table :dividends do |t| 4 | t.bigint :withheld_tax_cents 5 | t.bigint :net_amount_in_cents 6 | t.integer :withholding_percentage 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/spec/factories/consolidated_payment_balance_transactions.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :consolidated_payment_balance_transaction do 5 | company 6 | consolidated_payment 7 | amount_cents { 25_000_00 } 8 | transaction_type { BalanceTransaction::PAYMENT_INITIATED } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/spec/factories/dividend_payments.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :dividend_payment do 5 | dividends { [create(:dividend)] } 6 | wise_credential 7 | wise_recipient 8 | status { Payments::Status::INITIAL } 9 | processor_name { DividendPayment::PROCESSOR_WISE } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/factories/payments.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :payment do 5 | invoice 6 | wise_credential 7 | wise_recipient 8 | status { Payment::INITIAL } 9 | processor_uuid { SecureRandom.uuid } 10 | net_amount_in_cents { invoice.total_amount_in_usd_cents } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /frontend/components/Delta.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const Delta = ({ diff }: { diff: number | bigint }) => ( 4 | 0 ? "text-green" : diff < 0 ? "text-red" : "text-gray-500"}> 5 | {diff.toLocaleString(undefined, { style: "percent", maximumFractionDigits: 2 })} 6 | 7 | ); 8 | 9 | export default Delta; 10 | -------------------------------------------------------------------------------- /backend/app/models/company_administrator.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyAdministrator < ApplicationRecord 4 | include ExternalId 5 | 6 | belongs_to :company 7 | belongs_to :user 8 | 9 | has_many :contracts 10 | 11 | validates :user_id, uniqueness: { scope: :company_id } 12 | 13 | delegate :email, to: :user 14 | end 15 | -------------------------------------------------------------------------------- /backend/app/policies/document_templates_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DocumentTemplatesPolicy < ApplicationPolicy 4 | def index? 5 | company_administrator? 6 | end 7 | 8 | def show? 9 | company_administrator? || company_investor? 10 | end 11 | 12 | def update? 13 | company_administrator? 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/sidekiq/process_equity_grant_scheduled_vesting_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ProcessEquityGrantScheduledVestingJob 4 | include Sidekiq::Job 5 | 6 | def perform(equity_grant_id) 7 | equity_grant = EquityGrant.find(equity_grant_id) 8 | EquityGrant::UpdateVestedShares.new(equity_grant:).process 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/app/sidekiq/company_worker_tax_info_reminder_email_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyWorkerTaxInfoReminderEmailJob 4 | include Sidekiq::Job 5 | sidekiq_options retry: 5 6 | 7 | def perform(tax_year = Date.current.year - 1) 8 | CompanyWorkerReminderEmailService.new.confirm_tax_info_reminder(tax_year:) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/spec/factories/equity_grant_exercise_requests.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :equity_grant_exercise_request do 5 | equity_grant 6 | equity_grant_exercise 7 | 8 | number_of_options { equity_grant.vested_shares } 9 | exercise_price_usd { equity_grant.exercise_price_usd } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/factories/tender_offer_bids.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :tender_offer_bid do 5 | tender_offer 6 | company_investor { create(:company_investor, company: tender_offer.company) } 7 | number_of_shares { 100 } 8 | share_price_cents { 12_45 } 9 | share_class { "A" } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/test/mailers/previews/company_lawyer_mailer_preview.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyLawyerMailerPreview < ActionMailer::Preview 4 | def invitation_instructions 5 | company_lawyer = CompanyLawyer.last 6 | 7 | CompanyLawyerMailer.invitation_instructions( 8 | lawyer_id: company_lawyer.id 9 | ) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /frontend/app/(dashboard)/support/tools.ts: -------------------------------------------------------------------------------- 1 | export const helperTools = ({ companyId, contractorId }: { companyId: string; contractorId: string | undefined }) => ({ 2 | getInvoices: { 3 | description: "Fetch a list of recent invoices", 4 | parameters: {}, 5 | url: `/api/helper/invoices?companyId=${companyId}&contractorId=${contractorId ?? ""}`, 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Flexile", 3 | "icons": [ 4 | { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" }, 5 | { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" } 6 | ], 7 | "start_url": "/", 8 | "display": "standalone", 9 | "background_color": "#000000", 10 | "theme_color": "#000000" 11 | } 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20230816054447_create_dividend_computations.rb: -------------------------------------------------------------------------------- 1 | class CreateDividendComputations < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :dividend_computations do |t| 4 | t.references :company, null: false, index: true 5 | t.decimal :total_amount_in_usd, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/app/mailers/admin_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class AdminMailer < ApplicationMailer 4 | def custom(to:, subject:, body:, attached: {}) 5 | attached.each_pair do |key, value| 6 | attachments[key] = value 7 | end 8 | mail(to:, subject:) do |format| 9 | format.html { render html: body } 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/models/document_template.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DocumentTemplate < ApplicationRecord 4 | belongs_to :company 5 | 6 | enum :document_type, { 7 | consulting_contract: 0, 8 | exercise_notice: 1, 9 | letter_of_transmittal: 2, 10 | stock_option_agreement: 3, 11 | } 12 | 13 | validates :text, presence: true 14 | end 15 | -------------------------------------------------------------------------------- /backend/db/migrate/20220201112650_create_company_administrators.rb: -------------------------------------------------------------------------------- 1 | class CreateCompanyAdministrators < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :company_administrators do |t| 4 | t.references :user, null: false, index: true 5 | t.references :company, null: false, index: true 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20240821080832_change_tender_offer_bid_number_of_shares_to_decimal.rb: -------------------------------------------------------------------------------- 1 | class ChangeTenderOfferBidNumberOfSharesToDecimal < ActiveRecord::Migration[7.1] 2 | def up 3 | change_column :tender_offer_bids, :number_of_shares, :decimal 4 | end 5 | 6 | def down 7 | change_column :tender_offer_bids, :number_of_shares, :integer 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20240912094702_add_option_grant_type_to_equity_grants.rb: -------------------------------------------------------------------------------- 1 | class AddOptionGrantTypeToEquityGrants < ActiveRecord::Migration[7.2] 2 | def change 3 | create_enum :equity_grants_option_grant_type, %w[iso nso] 4 | add_column :equity_grants, :option_grant_type, :enum, enum_type: :equity_grants_option_grant_type, null: false, default: "nso" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /frontend/images/default-company-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/app/mailers/devise_mailer.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DeviseMailer < Devise::Mailer 4 | helper :application 5 | include Devise::Controllers::UrlHelpers 6 | layout "mailer" 7 | 8 | def invitation_instructions(record, token, opts = {}) 9 | @dividend_date = opts.delete(:dividend_date) 10 | super(record, token, opts) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/config/initializers/rspec_github_formatter_patch.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | if ENV["CI"].present? 4 | require "rspec/github" 5 | module RSpec 6 | module Github 7 | class Formatter 8 | def example_pending(_pending) 9 | # Disable annotations for pending specs 10 | end 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/spec/models/document_signature_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe DocumentSignature do 4 | describe "associations" do 5 | it { is_expected.to belong_to(:document) } 6 | it { is_expected.to belong_to(:user) } 7 | end 8 | 9 | describe "validations" do 10 | it { is_expected.to validate_presence_of(:title) } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/assets/images/default-company-logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/db/migrate/20220316205140_add_legal_info_columns_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddLegalInfoColumnsToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | change_table :users, bulk: true do |t| 4 | t.date :birth_date 5 | t.string :tax_id_number 6 | t.string :street_address 7 | t.string :city 8 | t.string :zip_code 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20220824085245_create_consolidated_invoices_invoice.rb: -------------------------------------------------------------------------------- 1 | class CreateConsolidatedInvoicesInvoice < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :consolidated_invoices_invoices do |t| 4 | t.references :consolidated_invoice, null: false 5 | t.references :invoice, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20220914082930_create_contracts.rb: -------------------------------------------------------------------------------- 1 | class CreateContracts < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :contracts do |t| 4 | t.datetime :signed_at 5 | t.references :company_contractor, index: true 6 | t.references :company_administrator, null: false, index: true 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20240103054838_create_dividends_dividend_payments.rb: -------------------------------------------------------------------------------- 1 | class CreateDividendsDividendPayments < ActiveRecord::Migration[7.1] 2 | def change 3 | create_table :dividends_dividend_payments, id: false do |t| 4 | t.belongs_to :dividend, null: false 5 | t.belongs_to :dividend_payment, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20240717041849_add_fully_diluted_shares_to_company_investor.rb: -------------------------------------------------------------------------------- 1 | class AddFullyDilutedSharesToCompanyInvestor < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :company_investors, :fully_diluted_shares, :virtual, 4 | type: :bigint, 5 | as: "(total_shares + total_options)", 6 | stored: true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20250605160217_remove_upcoming_dividend_cents.rb: -------------------------------------------------------------------------------- 1 | class RemoveUpcomingDividendCents < ActiveRecord::Migration[7.1] 2 | def change 3 | remove_column :companies, :upcoming_dividend_cents, :bigint 4 | remove_column :company_investors, :upcoming_dividend_cents, :bigint 5 | remove_column :convertible_investments, :upcoming_dividend_cents, :bigint 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/factories/dividend_rounds.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :dividend_round do 5 | company 6 | issued_at { 1.day.ago } 7 | number_of_shares { 100 } 8 | number_of_shareholders { 10 } 9 | total_amount_in_cents { 230_01 } 10 | status { "Issued" } 11 | return_of_capital { false } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/spec/factories/equity_buyback_payments.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :equity_buyback_payment do 5 | equity_buybacks { [create(:equity_buyback)] } 6 | wise_credential 7 | wise_recipient 8 | status { Payments::Status::INITIAL } 9 | processor_name { EquityBuybackPayment::PROCESSOR_WISE } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/models/tos_agreement_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.describe TosAgreement do 4 | describe "associations" do 5 | it { is_expected.to belong_to(:user) } 6 | end 7 | 8 | describe "validations" do 9 | it { is_expected.to validate_presence_of(:user_id) } 10 | it { is_expected.to validate_presence_of(:ip_address) } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/controllers/internal/settings/equity_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Internal::Settings::EquityController < Internal::Settings::BaseController 4 | after_action :verify_authorized 5 | 6 | def update 7 | authorize [:settings, :equity] 8 | Current.company_worker.update!(equity_percentage: params[:equity_percentage]) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/spec/factories/option_pools.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :option_pool do 5 | company 6 | share_class 7 | name { "Best equity plan" } 8 | authorized_shares { 100 } 9 | issued_shares { 50 } 10 | 11 | # So that `available_shares` is loaded correctly 12 | after(:create) { _1.reload } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /frontend/env/client.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | // Next inlines env variables in the client bundle, so we need to list them out here 4 | const env = { 5 | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, 6 | }; 7 | 8 | export default z 9 | .object({ 10 | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: z.string(), 11 | }) 12 | .parse(env); 13 | -------------------------------------------------------------------------------- /backend/app/sidekiq/company_administrator_tax_form_review_email_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyAdministratorTaxFormReviewEmailJob 4 | include Sidekiq::Job 5 | sidekiq_options retry: 5 6 | 7 | def perform(company_id, tax_year = Date.current.year - 1) 8 | CompanyAdministratorTaxFormReviewEmailService.new(company_id, tax_year).process 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20240401165753_track_wise_account_holder_name.rb: -------------------------------------------------------------------------------- 1 | class TrackWiseAccountHolderName < ActiveRecord::Migration[7.1] 2 | def change 3 | add_column :wise_recipients, :account_holder_name, :string 4 | add_reference :payments, :wise_recipient 5 | add_reference :dividend_payments, :wise_recipient 6 | add_reference :consolidated_payments, :wise_recipient 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20250426024711_remove_trial_fields_from_database.rb: -------------------------------------------------------------------------------- 1 | class RemoveTrialFieldsFromDatabase < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :company_roles, :trial_enabled, :boolean 4 | 5 | remove_column :company_role_rates, :trial_pay_rate_in_subunits, :integer 6 | 7 | remove_column :company_contractors, :on_trial, :boolean 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/spec/factories/consolidated_payments.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :consolidated_payment do 5 | consolidated_invoice 6 | status { ConsolidatedPayment::INITIAL } 7 | 8 | trait :succeeded do 9 | association :consolidated_invoice, :paid 10 | status { ConsolidatedPayment::SUCCEEDED } 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/spec/factories/invoice_approvals.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :invoice_approval do 5 | invoice 6 | approved_at { Time.current } 7 | 8 | after(:build) do |invoice_approval| 9 | invoice_approval.approver ||= create(:company_administrator, company: invoice_approval.invoice.company).user 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/db/migrate/20230417195608_create_company_investors.rb: -------------------------------------------------------------------------------- 1 | class CreateCompanyInvestors < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :company_investors do |t| 4 | t.references :user, null: false 5 | t.references :company, null: false 6 | 7 | t.timestamps 8 | 9 | t.index [ :user_id, :company_id ], unique: true 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/db/migrate/20230722214918_modify_convertible_investment.rb: -------------------------------------------------------------------------------- 1 | class ModifyConvertibleInvestment < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :convertible_investments, :identifier, :string, null: false 4 | add_column :convertible_investments, :entity_name, :string, null: false 5 | add_column :convertible_investments, :issued_at, :datetime, null: false 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20230824141215_change_dividend_computation_output.rb: -------------------------------------------------------------------------------- 1 | class ChangeDividendComputationOutput < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_reference :dividend_computation_outputs, :security, polymorphic: true 4 | add_column :dividend_computation_outputs, :investor_name, :string 5 | add_reference :dividend_computation_outputs, :company_investor 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # See https://git-scm.com/docs/gitattributes for more about git attribute files. 2 | 3 | # Mark the database schema as having been generated. 4 | db/schema.rb linguist-generated 5 | 6 | # Mark any vendored files as having been vendored. 7 | vendor/* linguist-vendored 8 | 9 | config/credentials/*.yml.enc diff=rails_credentials 10 | config/credentials.yml.enc diff=rails_credentials 11 | -------------------------------------------------------------------------------- /backend/app/policies/dividend_computation_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DividendComputationPolicy < ApplicationPolicy 4 | def index? 5 | return false unless company.equity_enabled? 6 | 7 | company_administrator.present? || company_lawyer.present? 8 | end 9 | 10 | def create? 11 | index? 12 | end 13 | 14 | def show? 15 | index? 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/config/domain.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Simple configuration that relies on environment variables being set appropriately for each environment 4 | PROTOCOL = ENV.fetch("PROTOCOL", "https") 5 | ROOT_DOMAIN = ENV.fetch("DOMAIN") 6 | DOMAIN = ENV.fetch("APP_DOMAIN", ROOT_DOMAIN) 7 | API_DOMAIN = ENV.fetch("API_DOMAIN", ROOT_DOMAIN) 8 | EMAIL_DOMAIN = ENV.fetch("EMAIL_DOMAIN", ROOT_DOMAIN) 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20240604171705_create_company_role_rates.rb: -------------------------------------------------------------------------------- 1 | class CreateCompanyRoleRates < ActiveRecord::Migration[7.1] 2 | def change 3 | create_table :company_role_rates do |t| 4 | t.integer :pay_rate_type, null: false, default: 0 5 | t.integer :pay_rate_usd, null: false 6 | t.references :company_role, null: false 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/services/default_invoice_date.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DefaultInvoiceDate 4 | def initialize(user, company) 5 | @user = user 6 | @company = company 7 | end 8 | 9 | def generate 10 | basic_default_date 11 | end 12 | 13 | private 14 | attr_reader :user, :company 15 | 16 | def basic_default_date 17 | Date.current 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /backend/app/controllers/internal/companies/share_classes_controller.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class Internal::Companies::ShareClassesController < Internal::Companies::BaseController 4 | def index 5 | authorize ShareClass 6 | 7 | share_classes = Current.company.share_classes.select(:id, :name) 8 | render json: share_classes.as_json(only: [:id, :name]) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/app/models/equity_exercise_bank_account.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class EquityExerciseBankAccount < ApplicationRecord 4 | belongs_to :company 5 | 6 | encrypts :account_number 7 | 8 | validates :details, presence: true 9 | validates :account_number, presence: true 10 | 11 | def all_details 12 | { "Account number" => account_number, **details.to_h } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/app/sidekiq/user_tax_form_review_reminder_email_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class UserTaxFormReviewReminderEmailJob 4 | include Sidekiq::Worker 5 | sidekiq_options retry: 5 6 | 7 | def perform(user_compliance_info_id, company_id, tax_year = Date.current.year) 8 | UserMailer.tax_form_review_reminder(user_compliance_info_id, company_id, tax_year).deliver_now 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20220317144815_create_table_wise_recipients.rb: -------------------------------------------------------------------------------- 1 | class CreateTableWiseRecipients < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :wise_recipients do |t| 4 | t.references :user, null: false, index: true 5 | t.string :recipient_id, null: false 6 | t.string :bank_name 7 | t.string :last_four_digits 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20231005135221_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from active_storage (originally 20211119233751) 2 | class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[6.0] 3 | def change 4 | return unless table_exists?(:active_storage_blobs) 5 | 6 | change_column_null(:active_storage_blobs, :checksum, true) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20240417102901_create_equity_exercise_bank_account.rb: -------------------------------------------------------------------------------- 1 | class CreateEquityExerciseBankAccount < ActiveRecord::Migration[7.1] 2 | def change 3 | create_table :equity_exercise_bank_accounts do |t| 4 | t.references :company, null: false 5 | t.jsonb :details, null: false 6 | t.string :account_number, null: false 7 | 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20241123235931_add_not_null_to_company_lawyer_external_id.rb: -------------------------------------------------------------------------------- 1 | class AddNotNullToCompanyLawyerExternalId < ActiveRecord::Migration[7.2] 2 | def change 3 | CompanyLawyer.where(external_id: nil).find_each do |lawyer| 4 | ExternalId::ExternalIdGenerator.process(lawyer) 5 | lawyer.save! 6 | end 7 | change_column_null :company_lawyers, :external_id, false 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/spec/factories/equity_buyback_rounds.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :equity_buyback_round do 5 | company 6 | tender_offer { create(:tender_offer, company:) } 7 | issued_at { 1.day.ago } 8 | number_of_shares { 100 } 9 | number_of_shareholders { 10 } 10 | total_amount_cents { 10_000_00 } 11 | status { "Issued" } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/test/mailers/previews/company_administrator_mailer_preview.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyAdministratorMailerPreview < ActionMailer::Preview 4 | def invitation_instructions 5 | company_administrator = CompanyAdministrator.last 6 | 7 | CompanyAdministratorMailer.invitation_instructions( 8 | administrator_id: company_administrator.id 9 | ) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/policies/dividend_round_policy.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class DividendRoundPolicy < ApplicationPolicy 4 | def index? 5 | return unless company.equity_enabled? 6 | 7 | company_administrator.present? || company_lawyer.present? 8 | end 9 | 10 | def create? 11 | return false unless company.equity_enabled? 12 | 13 | company_administrator.present? 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/services/company_worker_reminder_email_service.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class CompanyWorkerReminderEmailService 4 | def confirm_tax_info_reminder(tax_year:) 5 | CompanyWorker.with_required_tax_info_for(tax_year:).find_each do |contractor| 6 | CompanyWorkerMailer.confirm_tax_info_reminder(company_worker_id: contractor.id, tax_year:).deliver_later 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20230816045639_create_share_classes.rb: -------------------------------------------------------------------------------- 1 | class CreateShareClasses < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :share_classes do |t| 4 | t.references :company, null: false, index: true 5 | t.string :name, null: false 6 | t.decimal :original_issue_price_in_dollars 7 | t.decimal :hurdle_rate 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/db/migrate/20240906084605_create_equity_buybacks_equity_buyback_payments.rb: -------------------------------------------------------------------------------- 1 | class CreateEquityBuybacksEquityBuybackPayments < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :equity_buybacks_equity_buyback_payments do |t| 4 | t.belongs_to :equity_buyback, null: false 5 | t.belongs_to :equity_buyback_payment, null: false 6 | 7 | t.timestamps 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20250206171055_create_cap_table_uploads.rb: -------------------------------------------------------------------------------- 1 | class CreateCapTableUploads < ActiveRecord::Migration[7.2] 2 | def change 3 | create_table :cap_table_uploads do |t| 4 | t.references :company, null: false 5 | t.references :user, null: false 6 | t.datetime :uploaded_at, null: false 7 | t.string :status, null: false 8 | 9 | t.timestamps 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/spec/factories/convertible_securities.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :convertible_security do 5 | company_investor 6 | convertible_investment { association :convertible_investment, company: company_investor.company } 7 | principal_value_in_cents { 1_000_000_00 } 8 | implied_shares { 25_123 } 9 | issued_at { 1.year.ago } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/factories/wise_recipients.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :wise_recipient do 5 | user 6 | wise_credential 7 | 8 | country_code { "US" } 9 | currency { "USD" } 10 | recipient_id { "148563324" } # Test Wise Sandbox Recipient ID 11 | last_four_digits { "1234" } 12 | account_holder_name { "Jane Q. Contractor" } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/db/migrate/20241204162450_drop_pay_rate_usd_columns.rb: -------------------------------------------------------------------------------- 1 | class DropPayRateUsdColumns < ActiveRecord::Migration[7.2] 2 | def change 3 | remove_column :company_contractors, :pay_rate_usd, :integer 4 | remove_column :company_role_rates, :pay_rate_usd, :integer 5 | remove_column :company_role_rates, :trial_pay_rate_usd, :integer 6 | remove_column :invoice_line_items, :pay_rate_usd, :integer 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20250129155701_add_ready_for_payment_to_dividend_round.rb: -------------------------------------------------------------------------------- 1 | class AddReadyForPaymentToDividendRound < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :dividend_rounds, :ready_for_payment, :boolean, default: false, null: false 4 | 5 | up_only do 6 | DividendRound.reset_column_information 7 | DividendRound.update_all(ready_for_payment: true) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20250812164518_remove_unused_company_update_columns.rb: -------------------------------------------------------------------------------- 1 | class RemoveUnusedCompanyUpdateColumns < ActiveRecord::Migration[8.0] 2 | def change 3 | remove_column :company_updates, :period, :string 4 | remove_column :company_updates, :period_started_on, :date 5 | remove_column :company_updates, :show_revenue, :boolean 6 | remove_column :company_updates, :show_net_income, :boolean 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/support/rich_text_editor_helpers.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module RichTextEditorHelpers 4 | def find_rich_text_editor(name) 5 | find(:xpath, XPath.descendant[XPath.attr(:id) == XPath.anywhere(:label)[XPath.string.n.is(name)].attr(:for)]) 6 | end 7 | 8 | def fill_in_rich_text_editor(name, with:) 9 | node = find_rich_text_editor(name) 10 | node.set(with) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/db/migrate/20240927195452_add_update_attributes_to_tasks.rb: -------------------------------------------------------------------------------- 1 | class AddUpdateAttributesToTasks < ActiveRecord::Migration[7.2] 2 | def up 3 | change_table :tasks do |t| 4 | t.datetime :completed_at 5 | t.change :name, :text 6 | end 7 | end 8 | 9 | def down 10 | change_table :tasks do |t| 11 | t.change :name, :string 12 | t.remove :completed_at 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/views/devise_mailer/email_changed.html.erb: -------------------------------------------------------------------------------- 1 | <% if @resource.try(:unconfirmed_email?) %> 2 |11 | If you didn't request this, contact us immediately at <%= ApplicationMailer::SUPPORT_EMAIL %>. 12 |
13 | -------------------------------------------------------------------------------- /backend/db/migrate/20220516185836_make_counry_code_not_null.rb: -------------------------------------------------------------------------------- 1 | class MakeCounryCodeNotNull < ActiveRecord::Migration[7.0] 2 | def up 3 | if Rails.env.development? 4 | WiseRecipient.all.each { |wr| wr.destroy! unless wr.valid? } 5 | end 6 | change_column_null :wise_recipients, :country_code, false 7 | end 8 | 9 | def down 10 | change_column_null :wise_recipients, :country_code, true 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/db/migrate/20240918102312_change_board_approval_date_in_equity_grants_to_not_null.rb: -------------------------------------------------------------------------------- 1 | class ChangeBoardApprovalDateInEquityGrantsToNotNull < ActiveRecord::Migration[7.2] 2 | def change 3 | up_only do 4 | EquityGrant.where(board_approval_date: nil).find_each { _1.update!(board_approval_date: _1.issued_at) } 5 | end 6 | 7 | change_column_null :equity_grants, :board_approval_date, false 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/db/migrate/20250106170939_add_end_of_period_forfeiture_equity_grant_transaction_type.rb: -------------------------------------------------------------------------------- 1 | class AddEndOfPeriodForfeitureEquityGrantTransactionType < ActiveRecord::Migration[7.2] 2 | # NOTE: intentionally irreversible. See https://guides.rubyonrails.org/active_record_postgresql.html#enumerated-types 3 | def change 4 | add_enum_value :equity_grant_transactions_transaction_type, "end_of_period_forfeiture" 5 | end 6 | end 7 | 8 | -------------------------------------------------------------------------------- /backend/spec/factories/invoice_expenses.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | FactoryBot.define do 4 | factory :invoice_expense do 5 | invoice 6 | expense_category 7 | total_amount_in_cents { 1_000_00 } 8 | description { "American Airlines" } 9 | attachment { { io: File.open(Rails.root.join("spec/fixtures/files/sample.pdf")), filename: "expense.pdf", content_type: "application/pdf" } } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /bin/lint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | pnpm next lint frontend --fix --max-warnings 0 6 | pnpm tsc -p e2e/tsconfig.json 7 | pnpm eslint --fix --max-warnings 0 8 | pnpm prettier --write '**/*.{css,md,json}' --check '!docker' 9 | pnpm svgo --multipass backend/app/assets/**/*.svg 10 | pnpm svgo --multipass frontend/**/*.svg 11 | cd backend 12 | bundle exec rubocop -a 13 | bundle exec erb_lint --lint-all --format compact -a 14 | -------------------------------------------------------------------------------- /backend/app/fields/stripe_payment_intent_id_field.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require "administrate/field/base" 4 | 5 | class StripePaymentIntentIdField < Administrate::Field::Base 6 | def stripe_payment_dashboard_link 7 | if Rails.env.production? 8 | "https://dashboard.stripe.com/payments/#{data}" 9 | else 10 | "https://dashboard.stripe.com/test/payments/#{data}" 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/config/initializers/country.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | raw_countries = JSON.load_file("#{Rails.root}/config/countries.json") 4 | COUNTRY_CODES = raw_countries.keys 5 | SUPPORTED_COUNTRY_CODES = raw_countries.select { |_, v| v["supportsWisePayout"] }.keys 6 | SANCTIONED_COUNTRY_CODES = raw_countries.select { |_, v| v["sanctioned"] }.keys 7 | TAX_TREATY_COUNTRY_CODES = raw_countries.select { |_, v| v["hasTaxTreaty"] }.keys 8 | -------------------------------------------------------------------------------- /backend/lib/aws_s3_client_timecop.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Prevents Aws::S3::Errors::RequestTimeTooSkewed error by resetting the clock, when Timecop is used 4 | # 5 | module AwsS3ClientTimecop 6 | def put_object(*args, **kwargs) 7 | if defined?(Timecop) 8 | Timecop.return do 9 | super(*args, **kwargs) 10 | end 11 | else 12 | super(*args, **kwargs) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /patches/server-only.patch: -------------------------------------------------------------------------------- 1 | diff --git a/index.js b/index.js 2 | index e480b5cf2285aae782298399c110d5a2bf816deb..81691ebbebf0d3adf4bad5924b57a308dbd92a29 100644 3 | --- a/index.js 4 | +++ b/index.js 5 | @@ -1,4 +1,4 @@ 6 | -throw new Error( 7 | +if(process.env.NODE_ENV !== "test") throw new Error( 8 | "This module cannot be imported from a Client Component module. " + 9 | "It should only be used from a Server Component." 10 | ); 11 | -------------------------------------------------------------------------------- /backend/app/sidekiq/process_scheduled_vesting_for_equity_grants_job.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | class ProcessScheduledVestingForEquityGrantsJob 4 | include Sidekiq::Job 5 | 6 | def perform 7 | EquityGrant 8 | .vesting_trigger_scheduled 9 | .period_not_ended 10 | .accepted 11 | .find_each do 12 | ProcessEquityGrantScheduledVestingJob.perform_async(_1.id) 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/config/initializers/date_formats.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | Date::DATE_FORMATS[:short] = "%-d %b" # Date with no zero-padding + Short Month name 4 | Date::DATE_FORMATS[:medium] = "%b %-d, %Y" # Date with no zero-padding + Short Month name + Year 5 | Date::DATE_FORMATS[:long] = "%B %-d, %Y" # Date with no zero-padding + Long Month name + Year 6 | Date::DATE_FORMATS[:us_date] = "%-m/%-d/%Y" # Month/Date/Year with no zero-padding 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20221220152354_create_integration_records.rb: -------------------------------------------------------------------------------- 1 | class CreateIntegrationRecords < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :integration_records do |t| 4 | t.references :integration, null: false, index: true 5 | t.references :integratable, polymorphic: true 6 | t.string :external_id, null: false 7 | t.string :sync_token 8 | t.timestamps 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/db/migrate/20241122193554_remove_null_contraints_pay_rate_usd.rb: -------------------------------------------------------------------------------- 1 | class RemoveNullContraintsPayRateUsd < ActiveRecord::Migration[7.2] 2 | def change 3 | change_column_null :company_contractors, :pay_rate_usd, true 4 | change_column_null :company_role_rates, :pay_rate_usd, true 5 | change_column_null :company_role_rates, :trial_pay_rate_usd, true 6 | change_column_null :invoice_line_items, :pay_rate_usd, true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20241129095301_add_cap_table_enabled_to_companies.rb: -------------------------------------------------------------------------------- 1 | class AddCapTableEnabledToCompanies < ActiveRecord::Migration[7.2] 2 | def change 3 | add_column :companies, :cap_table_enabled, :boolean, default: false, null: false 4 | 5 | Company.reset_column_information 6 | Company.find_each do |company| 7 | company.update!(cap_table_enabled: Flipper.enabled?(:cap_table, company)) 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /frontend/trpc/routes/support.ts: -------------------------------------------------------------------------------- 1 | import { generateHelperAuth } from "@helperai/client/auth"; 2 | import env from "@/env"; 3 | import { createRouter, protectedProcedure } from "@/trpc"; 4 | 5 | export const supportRouter = createRouter({ 6 | createHelperSession: protectedProcedure.query(({ ctx }) => 7 | generateHelperAuth({ 8 | email: ctx.user.email, 9 | hmacSecret: env.HELPER_HMAC_SECRET, 10 | }), 11 | ), 12 | }); 13 | --------------------------------------------------------------------------------