You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
docuseal/REBRANDING.md

13 KiB

Rebranding Summary: DocuSeal → WaboSign

This document records the changes made when forking DocuSeal into WaboSign. It exists for transparency, to fulfil AGPLv3 §7(b) disclosure expectations, and as a reference for future maintainers tracing why a particular file was touched.

Scope: ~183 files modified. Decisions were made in a planning conversation before changes were applied; the final plan lives at .claude/plans/this-agpl-project-has-toasty-cake.md on the developer's machine.

Brand & identity

  • Ruby module DocusealWabosign (lib/wabosign.rb); Rails app module DocuSealWaboSign (config/application.rb)
  • All hardcoded DocuSeal strings in views, mailers, controllers, libs, JS/Vue replaced with Wabosign.product_name (or equivalents)
  • config/locales/i18n.yml: 168 user-facing strings sweep-replaced across all 14 languages
  • New favicons, apple-touch-icons, and logo SVG (a neutral "W" mark) generated via Inkscape
  • daisyUI theme renamed docusealwabosign in tailwind.config.js
  • Discord, Twitter, ChatGPT URLs removed entirely
  • New brand constants in lib/wabosign.rb:
    • PRODUCT_URL = 'https://sign.wabo.cc'
    • GITHUB_URL = 'https://github.com/wabolabs/wabosign'
    • SUPPORT_EMAIL = 'wabosign@wabo.cc'

AGPL §7(b) attribution

Freemium gates removed

Migrations & infrastructure

Intentionally preserved upstream references

Per AGPL §7(b) and downstream SDK compatibility, the following references remain. All are documented in NOTICE.

Verification status

  • Ruby syntax-checked all edited .rb files (lib, controllers, mailers, migration)
  • ERB-compiled the edited view partials
  • YAML-parsed config/locales/i18n.yml and docker-compose.yml
  • JSON-parsed docs/openapi.json
  • Webhook spec assertions updated to match new WaboSign Webhook user-agent

Full Rails boot requires Ruby 4.0.1, which was not available on the dev machine that performed the rebrand. Recommend running docker compose up --build to verify boot end-to-end before publishing.

Sync workflow

Upstream lives at docusealco/docuseal. Each upstream release is brought in by re-running a deterministic rebrand sweep on the upstream tree, then merging into master. The strategy details are in .claude/plans/come-up-with-a-foamy-flask.md; the short version follows.

Tooling

  • bin/rebrand-sync — Ruby script that performs the DocuSeal → WaboSign rename sweep across the working tree. Idempotent. Honors a deny-list (see §"Intentionally preserved upstream references" above) and sentinel-protects AGPL §7(b) attribution phrases, SDK custom-element names (docuseal-form, docuseal-builder), @docuseal/* npm packages, and the github.com/docusealco/{fields-detection,pdfium-binaries,turbo} binary URLs.
  • bin/rebrand-check — fails (exit 1) if any unintended DocuSeal reference survives. Wired into .github/workflows/ci.yml as the Rebrand check job.
  • git config rerere.enabled true && git config rerere.autoupdate true — once-per-checkout setup; remembers semantic conflict resolutions so the same call is not re-made each release.
  • .gitattributes marks Gemfile.lock and yarn.lock as -merge (regenerate after merge rather than diffing).

Per-sync steps

git fetch upstream --tags
git checkout -b sync/upstream-<tag> <tag>      # e.g. 3.0.0
bin/rebrand-sync
git add -A && git commit -m "Apply WaboSign rebrand sweep to upstream <tag>"

git checkout master
git merge --no-ff sync/upstream-<tag>
# Resolve conflicts. Rerere caches recurring resolutions.

# Restore WaboSign brand assets that the merge may have overwritten:
git checkout ORIG_HEAD -- public/favicon.svg public/favicon.ico \
  public/favicon-16x16.png public/favicon-32x32.png \
  public/favicon-96x96.png public/logo.svg

bin/rebrand-sync                                # catch upstream-only new files
bin/rebrand-check                               # CI gate

bundle install
yarn install

# Verify (see "Verification" in the plan), then:
git tag wabosign-synced-with-<tag>

Or use the automated script:

bin/sync-upstream <tag>

Adding new preserved tokens

When upstream introduces a new SDK identifier, binary URL, or attribution surface that must survive the sweep, edit PRESERVE in bin/rebrand-sync and ALLOW_PATTERNS in bin/rebrand-check together. The two must stay in sync — rebrand-sync decides what the sweep ignores, rebrand-check decides what CI tolerates.

Post-Merge Verification Checklist

Run through these checks after every upstream merge. The earlier failures are caught by bin/rebrand-check; the later ones require manual inspection or rspec.

Automatic (bin/rebrand-check)

  • Rebrand check passes (no unintended DocuSeal references)
  • RSpec suite passes (360+ examples, 0 failures)
  • app/views/shared/_powered_by.html.erb links both WaboSign and DocuSeal (upstream AGPL credit)
  • app/views/shared/_email_attribution.html.erb uses WaboSign product name, not DocuSeal
  • app/javascript/submission_form/completed.vue still has the hardcoded DocuSeal upstream credit

Logo / Branding

  • app/views/shared/_logo.html.erb shows the WaboSign "W" mark (not the DocuSeal abstract shape)
  • public/favicon.svg, public/logo.svg show the WaboSign "W" mark
  • app/views/shared/_account_logo.html.erb renders attached logo or falls back to the W mark

Console / Plans / Pro / Upgrade

  • app/controllers/console_redirect_controller.rb does not exist
  • config/routes.rb has no console_redirect, upgrade, or manage routes
  • app/controllers/sessions_controller.rb has no console_redirect_index_path call
  • lib/wabosign.rb has no CONSOLE_URL, CLOUD_URL, or CDN_URL constants
  • app/views/shared/_settings_nav.html.erb has no "Plans" link or "Pro" badge
  • app/views/shared/_navbar.html.erb has no "Console" link in dropdown
  • app/views/shared/_navbar_buttons.html.erb has no "Upgrade" button
  • No view file contains unlock_with_docuseal_pro, activate_with_docuseal_pro, or console_redirect_index_path

Feature Gates (all freely available)

  • app/views/sms_settings/index.html.erb shows provider form (BulkVS/Twilio/VoIP.ms/SignalWire) — not a placeholder
  • app/views/personalization_settings/_logo_placeholder.html.erb shows upload form — not a Pro upsell
  • app/views/notifications_settings/_reminder_placeholder.html.erb is empty (reminder form renders freely)
  • app/views/submissions/_bulk_send_placeholder.html.erb is empty (bulk send freely available)
  • app/views/submissions/_send_sms_button.html.erb is a functional button (not Pro-gated tooltip)
  • app/views/users/_role_select.html.erb has no disabled options or Pro upsell link
  • app/views/accounts/show.html.erb has no console-redirect Pro gates on Decline/Delegate toggles

Google SSO

  • app/views/sso_settings/index.html.erb shows the Google SSO config form (client_id, client_secret, allowed_domains)
  • app/views/devise/sessions/_omniauthable.html.erb has the "Sign in with Google" button
  • app/views/sso_settings/_placeholder.html.erb does not exist (was replaced by the real form)
  • OmniAuth routes for auth/google_oauth2 are present in config/routes.rb

E-Signature Settings

  • app/views/esign_settings/_default_signature_row.html.erb does not exist
  • config/locales/i18n.yml has no wabosign_trusted_signature or sign_documents_with_trusted_certificate_* keys

Social / Extras

  • app/views/shared/_github.html.erb does not exist (no hardcoded star count)
  • app/views/shared/_navbar.html.erb does not render shared/github or shared/github_button
  • app/views/shared/_settings_nav.html.erb has no Discord or AI Assistant links in support channels
  • config/locales/i18n.yml has no discord_community or ai_assistant keys

SMS (independently developed)

  • app/views/sms_settings/index.html.erb is the full provider form (not placeholder)
  • lib/sms.rb exists with all 4 providers (BulkVS, Twilio, VoIP.ms, SignalWire)
  • lib/sms/providers/ directory exists with all 4 provider implementations
  • app/controllers/sms_settings_controller.rb handles test_message action
  • app/models/encrypted_config.rb has SMS_CONFIGS_KEY = 'sms_configs' constant
  • config/routes.rb has the SMS routes with test_message collection route