Replace non-breaking space (U+00A0) with regular space in
percent_space number format template literal. Upstream used
a literal NBSP for French-style typographic spacing.
* fix: add team factory and associate with user factory
The Teams feature added a NOT NULL team_id constraint on users.
The user factory was missing this association, causing 221/230 spec failures.
* fix: make local CI match GitHub Actions 1:1
- Dockerfile.ci: add chromium, chromedriver, pdfium (same as remote CI)
- docker-compose.ci.yml: fix PG18 tmpfs mount path (/var/lib/postgresql)
- .githooks/pre-push: run FULL CI suite (lint + brakeman + rspec)
Local CI results: 230 examples, 2 failures (system spec browser issues,
pre-existing — same tests fail on remote CI too)
* fix: resolve failing RSpec tests (setup + signing form)
- setup_spec.rb:28: move team assignment before @account.valid? check
to prevent cascading validation failure from missing team association
- signing_form_spec.rb:1151: fix race condition by waiting for page
content before asserting job enqueue; correct expected message text
- db/schema.rb: update to reflect teams migrations
* fix: resolve remaining flaky test failures
- dashboard_spec.rb: use deterministic template name to prevent
Faker::Book.title collisions between account templates
- rails_helper.rb: increase Cuprite timeout from 20s to 30s to
prevent PendingConnectionsError on first page load in CI
---------
Co-authored-by: Sebastian Noe <sebastian.schneider@boxine.de>
* fix: resolve all Rubocop and ERBLint offenses
Rubocop (16 offenses):
- Style/IfUnlessModifier in account_logo_controller
- Lint/RedundantSafeNavigation in templates_documents_controller
- Layout/LineLength in templates_documents_controller, account_config
- Rails/WhereMissing in teams_controller
- Rails/WhereExists in send_submitter_reminder_email_job
- Style/StringLiterals in create_teams migration
- Metrics/* (disabled via inline comments for complex case statements)
ERBLint (10 errors):
- Void element self-closing tags (img /> → img >)
- Layout/ArgumentAlignment in reminder_queue
- Style/StringLiterals + Rails/LinkToBlank in navbar_buttons
- Layout/BlockAlignment in custom_content mailer
- Style/WordArray in role_select
* feat: add local CI via Docker and pre-push lint hook
- Add docker-compose.ci.yml: lint, brakeman, rspec services
- Add Dockerfile.ci: test environment with Ruby, Node, Chromium
- Add bin/lint: quick lint-only check
- Add bin/ci: full CI suite (lint + brakeman + rspec)
- Add .githooks/pre-push: auto-runs linters before push
- Update docker-compose.yml: use ghcr.io image instead of local build
Setup: git config core.hooksPath .githooks
Usage: bin/ci or bin/lint
---------
Co-authored-by: Sebastian Noe <sebastian.schneider@boxine.de>
Add optional 'revision' parameter to PUT /api/templates/:id and
PUT /api/templates/:id/documents. When present, creates a template
version snapshot (same mechanism as the UI editor's Save button).
This enables API consumers (e.g., deploy-docuseal.py) to create
revision history entries when updating templates programmatically.
Usage: include "revision": true in the request body.
Omit the parameter to skip version creation (backwards compatible).
Upstream changes:
- Template revision history (save/view/revert template versions)
- HMAC webhook signature validation
- i18n fixes and updates
- Gem updates (hexapdf, nokogiri, net-imap)
- PDF rotation via pdfium
- Allow permanent delete of submissions in archived templates
- Retry webhooks in test mode
- Various bug fixes and style adjustments
Fork features preserved:
- Teams & Editor Role
- Email reminders
- Company logo / white-label
- Custom email templates
- Template creation API
- Navigation customization
* feat: add customizable reminder email templates
- Add SubmitterMailer#reminder_email with separate subject/body resolution
- Support per-template and per-account reminder email customization
- Add GUI forms for reminder email templates (account + template level)
- Add i18n keys for reminder emails and reminder visibility UI
- Update SendSubmitterReminderEmailJob to use reminder_email instead of invitation_email
- Add race condition guard (1-minute dedup) in send job
* fix: prevent reminder job duplication on container restart
- Add deduplication in scheduled_jobs.rb initializer (clear existing before scheduling)
- Add reschedule! method in ProcessSubmitterRemindersJob that clears stale copies
- Prevents exponential job accumulation across container restarts
* feat: add reminder visibility and queue management
- Add SubmitterReminders module (lib/) for next-reminder-at calculation
- Show next reminder time per submitter on submission page (with timezone tooltip)
- Add pending reminders queue table on notifications settings page
- Add Skip button to advance past current pending reminder (Turbo Stream)
- Add skip_reminder_email event type to SubmissionEvent
- Update ProcessSubmitterRemindersJob to count skip events in reminder_count
- Add SubmitterRemindersController with destroy action for skip
* docs: document reminder email templates feature in README
---------
Co-authored-by: Sebastian Noe <sebastian.schneider@boxine.de>
- Remove Discord, AI assistant, and support email from settings sidebar
- Remove Console and Plans menu items from sidebar and navbar dropdown
- Grey out SSO menu item (pro feature, not yet implemented)
- Rename 'Upgrade' button to 'Go Full Pro' linking to docuseal.com
- Point GitHub URL to snoe/docuseal-like-a-pro fork
- Replace hardcoded GitHub URLs with Docuseal::GITHUB_URL constant
Co-authored-by: Sebastian Noe <sebastian.schneider@boxine.de>
* feat(teams): add Team model and migrations
Create teams table with name, account_id, uuid, archived_at.
Add team_id foreign key to users, templates, submissions,
submitters, and template_folders. Backfill migration creates
a Default team per account and assigns all existing records.
* feat(teams): add team associations to models
User belongs_to team (required). Template, Submission, Submitter,
and TemplateFolder belong_to team (optional for backwards compat).
Account has_many teams with default_team helper. Add EDITOR_ROLE
to User::ROLES and editors scope.
* feat(auth): rewrite abilities with role + team scoping
Admin retains full account-wide access. Editor gets team-scoped
access to templates, submissions, submitters, folders, plus
account-wide access to AccountConfig and WebhookUrl.
ProfileController uses authorize!(:update) instead of :manage
so editors can access their own profile page.
* feat(teams): add team CRUD controller and views
Admin-only team management at /settings/teams. Create, edit,
and archive teams. Index view uses eager-loaded user counts
to avoid N+1 queries. Routes added in settings scope.
* feat(teams): add role and team selection to user management
Enable editor role in role select (remove Pro upsell gate).
Add team dropdown to user form visible to admins only.
Validate team_id belongs to current account on create.
* feat(teams): assign team_id on resource creation
Set team_id from current_user.team_id when creating templates,
submissions, submitters, and folders. Setup controller creates
Default team alongside first account for greenfield installs.
* feat(teams): add move-folder-to-team and editor settings access
Admins can move folders between teams via the folder edit modal.
Moving cascades team_id to all templates, submissions, and
submitters in a transaction. Editors can now access
personalization, API, and webhook settings.
* docs: document teams and roles feature in README
---------
Co-authored-by: Sebastian Noe <sebastian.schneider@boxine.de>
- Expose sender.name, sender.first_name, sender.email in all email type variable dropdowns
- Expose submitter.name, submitter.first_name, submitter.email in all email type variable dropdowns
- Add i18n translations for new variables across all 7 locales (EN, ES, IT, FR, PT, DE, NL)
- Fix logo form Save button: change f.submit to f.button to render HTML correctly
- Replace bare layout with table-based 600px card design
- Gray background, white content card, rounded corners
- Company logo in header (falls back to account name)
- Attribution footer inlined with subtle styling
- Add reusable _email_button partial (blue CTA, table-based)
- Update invitation, completed, documents_copy emails to use button
- Auto-convert submitter link to styled button in custom email bodies
- Remove deprecated _mailer_attribution and _email_attribution partials
- Preserve RTL support and all existing customization flows
- Add POST /api/templates/pdf for creating templates from PDF files
- Supports base64 content and URL file sources
- Supports external_id upsert, folder assignment, explicit field coords
- Supports embedded {{field;type=x;role=y}} text tag extraction
- Add PUT /api/templates/:id/documents for add/replace/remove operations
- Add Api::DecodeDocumentFile utility for shared base64/URL handling
- Add comprehensive API documentation in docs/API.md
- Add routes for new API endpoints
- Add has_one_attached :logo to Account model
- Add AccountLogoController for upload/delete in Settings
- Display custom logo in signing forms (start_form, submit_form)
- Display custom logo in submission preview
- Add logo upload form with drag-and-drop to personalization settings