COMPLIANCE
SARS valuation override policy for ESOP administrators
Detailed procedure for handling stale valuations, override attestations, and SARS Section 97 compliance.

Last reviewed: 2025-03-01

ESOP Policies and Behavioral Notes

  • Pool Reservation & Recycling: The ESOP pool calculation reserves capacity for all non-terminal grants, including PENDING_BOARD_APPROVAL, AWAITING_ACCEPTANCE_SIGNATURE, OFFERED, ACTIVE, and FULLY_EXERCISED. Exercised options remain reserved by default so the pool never "refills" without shareholder approval, and fully exercised grants stay blocked from the pool unless recycling is enabled. Schemes that explicitly recycle exercised shares can opt into the legacy behaviour by toggling the recycleExercisedShares flag; when enabled, dashboards and fully diluted share counts track the outstanding (recycled) option balance rather than the configured pool size. Terminated grants that have passed their legal expiryDate contribute only their exercised portion to the pool (outstanding balances drop to zero) unless recycling is explicitly enabled. BAD_LEAVER grants keep their vested balances reserved while their statutory/post-termination window remains open; only FOR_CAUSE terminations are stripped out immediately (see policy:termination-for-cause for forfeiture rules). When exit-only schemes keep the window closed, the pool continues to reserve the vested-but-locked portion (numberOfOptions − exercised − forfeited − lapsed) plus any shares already exercised so previously lapsed balances are not re-reserved but the exercised slice remains accounted for.
  • For-Cause Terminations: All unexercised options are forfeited immediately upon for-cause termination; any shares already exercised stay issued, but no further exercise is allowed. For-cause grants are excluded from terminated exercisable totals when calculating pool usage (see policy:vesting-pool-reservation), ensuring the pool never reserves capacity for options that are permanently forfeited under disciplinary exits. Exit acceleration never restores lapses or forfeits on FOR_CAUSE grants.

  • Exit Acceleration Policy: When accelerateOnExit is enabled the scheme fully vests active holders and GOOD_LEAVER terminations once the exit date arrives; BAD_LEAVER and FOR_CAUSE grants remain forfeited even during exit acceleration. The optional flag accelerateTerminatedGoodLeavers extends that behaviour to schemes that do not run full acceleration (e.g., exit-only unlocks without full acceleration) so terminated good leavers still accelerate, but it only clears recorded lapses/forfeits when restoreLapsedOptionsOnExit is enabled (and, for exit-only plans, when reopenExerciseWindowOnExit also stays on). Acceleration checks are evaluated deterministically at the same reference date used for vesting (termination date for terminated grants) so exports stay aligned. If the company postpones an exit, previously accelerated vesting events are unprocessed until the new date. Terminations processed after an exit – or grants marked BAD_LEAVER/FOR_CAUSE – retain their recorded lapses even if the scheme accelerated on exit.

  • Acceleration keeps the window open through the exit-day local end-of-day only; after that deadline, any remaining reinstated balance lapses and pool usage retains only the already exercised portion.
  • Termination flows compare the termination timestamp to the exit-day EOD deadline. If the termination timestamp is after the exit-day end-of-day (23:59:59.999 in company timezone), recorded lapses and forfeits remain in place even when restoreLapsedOptionsOnExit and window reopen toggles are enabled. This allows terminations on exit day (before EOD) to be eligible for reinstatement while the exit window is open.
    • Manual termination routes (single grant, bulk, and member deactivation) honour the legal termination timestamp while evaluating exit reinstatement against the current processing time. Reinstatement only applies while that processing clock remains before the company-local exit-day end-of-day; once the deadline passes, historical terminations retain their recorded lapses even if policy toggles are enabled.
  • Exercise APIs evaluate exit-day and legal-expiry deadlines against the submission timestamp. Backdated exerciseDate values are only accepted while the submission occurs before the relevant deadline; once the window closes, the request is rejected even if the payload supplies an earlier timestamp.
  • Grants marked EXPIRED solely because the legal instrument lapsed (no termination timestamp) are treated as active participants for exit acceleration and overrides, so their exercisable balance reopens during the exit window while the exits-only lock rules continue to apply to actual terminations.
  • When the exit-day override fires for these expiry-only grants, any lapses recorded by expiry jobs are reinstated automatically even if "Restore lapsed options on exit" remains disabled (reflected as effectiveLapsedOptions = 0 in getExerciseData responses), ensuring members recover the outstanding balance that policy guarantees during the exit window.
  • Exit-Only Exercise Schemes: When a scheme is configured as exit-only, exercisable and net outstanding amounts are clamped to zero until an exit event is recorded. Once an exit is logged, previously lapsed post-termination windows only reopen and reinstate balances when both “Restore lapsed options on exit” and “Reopen post-termination window on exit” are enabled. Keeping either toggle off preserves recorded lapses/forfeits so the pool and reporting remain conservative. Non exit-only plans still rely solely on the restoreLapsedOptionsOnExit flag; acceleration is not required to reinstate previously lapsed balances.
    • When administrators keep the toggle disabled, terminated holders remain locked even after the exit is recorded. This applies even if no post-termination lapse window was configured; the grant stays EXPIRED/TERMINATED with zero exercisable balance so the pool cannot be reused prematurely.
    • Derived exercise helpers keep windowExpired = true for these terminated grants until both toggles are enabled, preventing dashboards and exports from surfacing a reopened window that policy forbids.
    • Locked exit-only grants retain their original vested totals in reporting (netCumulativeVested stays at the pre-gating value) while netOutstanding is suppressed to 0. The nightly post-termination processor simply flips their stored status to EXPIRED once the exit-day deadline has passed and leaves recorded lapses/forfeits unchanged, ensuring pool reservations continue to carry the blocked balance.
    • Terminations captured during an exit-only reopening inherit the restored balance only when both toggles are enabled. Otherwise, the reinstatement stash retains the historical lapses/forfeits and the grant stays blocked.
    • Clearing or postponing an exit after such terminations no longer replays the old lapses because the reinstatement stash is dropped once the termination is persisted.
  • Exit-Day Deadline: When exit unlocks exercise (either via acceleration or exit-only rules), the effective exercise deadline is the end of the exit day in the resolved company timezone (falling back to the platform timezone, then UTC). The UI labels this as an “Exit event (end of day)” deadline so members see the exact local cut-off.
    • Platform APIs (getExerciseContext, notifications) always surface this exit-day deadline as deadlineType = EXIT_EVENT_EOD so downstream processes and alerts stay aligned.
    • Strict Expiry Option: Active grants always inherit the exit-day override so they can exercise even when their legal expiry has passed. The scheme toggle “Exit overrides grant expiry (exit day)” specifically controls whether eligible terminated holders (when restore-and, for exit-only plans, reopen policies allow them) receive the same override. Default is On; disable it only if your rules keep terminated holders locked after expiry even during an exit.
    • Pool reservation: Capacity calculations reserve terminated exit‑only grants before an exit. Exercised portions are always reserved; in aggregate fallbacks the system conservatively reserves vested‑but‑locked balances as well to avoid over‑allocation. Detailed per‑grant views will still show 0 exercisable prior to exit. When the reopen toggle is disabled the pool continues to reserve the terminated balance even after the exit is recorded so administrators cannot recycle the pool prematurely.
    • Reporting note: When an exit reopens an expired post‑termination window, statusEffective reflects the holder’s actual state: expiry-only grants (no termination timestamp) surface ACTIVE for the duration of the reopen, while terminated holders continue to surface TERMINATED. Once the exit-day deadline passes, both scenarios revert to EXPIRED. The original termination timestamp remains unchanged.
  • Post exit-day lapse: Once the exit-day local deadline has passed, any remaining vested-but-unexercised balance on exit-only terminated grants is moved to lapsedOptions automatically, marking the grant as EXPIRED. API endpoints also surface an statusEffective of EXPIRED immediately after the deadline so member dashboards and exports reflect the closed window even before the nightly lapse job persists the lifecycle change.
  • Revived expiries: Exit-only schemes revive expired grants for terminated holders only when both the restore and reopen toggles are on. Active participants always receive the exit-day override regardless of the toggles, so they can exercise even if the instrument expiry has passed. For non exit-only plans, enabling “Restore lapsed options on exit” temporarily treats previously EXPIRED grants as TERMINATED during the reopening so that post-termination notifications and lapse jobs continue to run. After the exit-day deadline the remaining balance lapses and the grant returns to EXPIRED.
  • Exit reinstatements store the original lapsed/forfeited balances while the exit is active, along with the exercised and outstanding baselines, ensuring that clearing or postponing the exit automatically restores the remaining totals after subtracting any options exercised during the reopening, without manual reconciliation. This applies to accelerated exits and to exit-only reopenings when the window is configured to reopen.
    • The single-grant termination API mirrors the bulk-terminate and member deactivation flows by persisting the exit reinstatement stash (exitRestored* fields) whenever restoration applies, so clearing or postponing an exit restores the exact pre-exit balances regardless of which termination surface was used.
  • Post-Termination Windows: After the post-termination exercise window lapses with no exit relief, exercisable and net-vested balances drop to zero to match statutory forfeiture. Any later acceleration or exit-only unlock recalculates from the shared vesting service so downstream consumers see the reopened totals immediately.
  • Auto-Exercise for UNRESTRICTED Schemes: When a scheme is configured as UNRESTRICTED (anytime exercise, exerciseOnExitOnly: false) and auto-exercise is enabled (autoExerciseEnabled: true), the platform automatically exercises vested options at each vesting event to trigger Section 8C tax obligations immediately. This solves the "paper gain" problem where employees owe PAYE on options they haven't exercised yet — under Section 8C, tax vesting occurs when UNRESTRICTED options become exercisable (at internal vesting), not when the employee chooses to exercise them. The settlement method follows the scheme configuration (autoExerciseSettlementMethod, default SHARE_WITHHOLDING but CASH is supported). When share withholding is selected the system withholds shares equal to the PAYE amount and issues the net balance; when cash settlement is selected the full option block is issued and the recorded PAYE amount is handed off to payroll for cash remittance. Auto-exercise processing includes 3 retry attempts with exponential backoff (1s, 2s, 4s delays) to handle transient failures. The feature is blocked during exit events (requires manual processing), requires a current valuation (max staleness: 183 days sourced from CompanyConfig.maxValuationStaleness, defaulting to 183 when unset), and only processes grants in ACTIVE status. Each auto-exercise is recorded with audit actions (AUTO_EXERCISE_COMPLETED, AUTO_EXERCISE_FAILED) and links to the originating vestingEventId for traceability. Idempotency checks prevent duplicate exercises for the same vesting event. This feature is gated by NEXT_PUBLIC_ENABLE_UNRESTRICTED_SCHEMES environment variable (default: false) — when disabled, only RESTRICTED (exit-only) schemes are available. See docs/reference/ESOP_SECTION_8C.md for tax implications and complete implementation details. Implementation: lib/services/exercise.service.ts (canAutoExercise(), autoExerciseAtVesting()), triggered by daily vesting cron job in lib/email-notifications.ts (processRegularVestingEvents()).
  • Invitation vs Option Expiry: Grant invitation validity is tracked via offerExpiresAt and is distinct from the instrument's option expiryDate (7–10 years or company policy). Accepting an offer is blocked only when offerExpiresAt (computed from the invitation issue timestamp) has passed. Both offer expiry and option expiry are evaluated at end‑of‑day (23:59:59.999) in the resolved company timezone (falling back to the platform timezone, then UTC via resolveTimezone).

    • End-of-Day Grace Period: Offer expiry uses the same end-of-day calculation as exercise windows for consistency. When an offer is set to expire on January 30, members can accept until 23:59:59.999 on January 30 in the company's local timezone. This ensures predictable behavior and aligns with the platform's general deadline pattern. Once that moment passes, the offer must be reissued or extended before acceptance can proceed.
    • Default Window: New offers default to 30 days from invitation issuance. This can be customized at three levels (in order of precedence): company-level configuration via Dashboard → Company → Configuration, the INVITE_DEFAULT_DAYS environment variable, or the hardcoded default of 30 days. Admins can still accept grants on behalf of users after the invite expires by reissuing or extending the offer.
  • Leaver Policies:

    • Good Leaver: preserves vested options as at termination date; unvested options forfeit. Post-termination exercise window may apply.
    • Bad Leaver: unvested options are forfeited immediately; vested options remain but may be repurchased at nominal value. The platform keeps their dashboards/access active until the legal exercise window lapses so they can action remaining rights.
    • For Cause: See policy:termination-for-cause above for complete forfeiture and pool treatment rules.
  • Termination eligibility check: Termination flows reject termination dates that fall before a grant's legal start date (grant date or vesting start). This keeps statutory vesting intact and ensures exit acceleration math evaluates from the correct employment reference. Attempts to terminate earlier than the grant start raise an error until the grant metadata is corrected.
  • Post-expiry guardrail: Termination submissions captured after the grant’s legal expiry end-of-day (23:59:59.999 in the resolved company timezone) are rejected across single-grant, bulk, and member deactivation flows. Submissions timestamped on the expiry date itself remain valid through that local deadline. Extend the option expiry (or capture the termination earlier) so the statutory post-termination window remains enforceable before filing the termination.
  • Last exercise ordering: Terminations must also fall on or after the holder's most recent exercise timestamp. Same-day submissions are only accepted when the termination time is equal to or later than the exercise. The shared termination validator enforces this ordering so the statutory window stays intact and regulators receive a chronological audit trail.
  • Termination audit log: Every admin surface requires both a precise termination timestamp (ISO 8601 datetime) and a descriptive termination reason (minimum 10 characters) so audit exports, emails, and downstream compliance reviews capture when and why the employee departed. Attempts without a sufficient reason or missing the timestamp are rejected. For additional details on timestamp normalization and timezone handling, see TIMEZONE_RULES.md.
  • Post-Termination Exercise Window Counting: The post-termination exercise window (lapse days) defines how many calendar days remain exercisable after termination. The termination date itself is the first exercisable day (day 1 of the window). A 30-day window means 30 full calendar days are exercisable starting from the termination date. The final exercisable day is calculated as termination date + (lapseDays - 1) calendar days at end-of-day in the company-local timezone. Why subtract 1? Because the termination date itself counts as day 1, we only need to add (lapseDays - 1) additional days to reach the final day. Example: A 30-day window from January 1 means: Day 1 = Jan 1, Day 30 = Jan 30. Calculation: Jan 1 + (30 - 1) days = Jan 1 + 29 days = Jan 30. The deadline is 23:59:59.999 on January 30 in the resolved company timezone, giving exactly 30 full calendar days (Jan 1 through Jan 30 inclusive). Window overrides must remain between 0 and 365 days. See lib/exercise-window.ts for implementation details and docs/guides/platform-user-guide.md for configuration guidance.
  • Exercise Window Timezone: Post‑termination exercise windows use the company-local timezone for deadline calculations. Callers must resolve the timezone via resolveTimezone({ companyId }) and pass it to exercise window functions like calculateExerciseWindowDeadline(). The resolution chain falls back from company timezone → platform timezone → UTC. If no timezone is passed to the calculation functions, they default to UTC. Deadlines honour DST changes so lapses end at the local 23:59:59. Configure your company timezone in settings so deadlines, alerts, and expiry processing align with local regulations.

  • Snapshot semantics (forfeits and lapses): Unless otherwise stated, reporting snapshots use policy‑effective values. In particular, forfeitedOptions reflects recorded forfeits plus any policy‑effective lapses at the snapshot time. When “Restore lapsed options on exit” is enabled and exit acceleration or an exit‑only unlock applies, effective lapses are reinstated (0) and the snapshot’s forfeitedOptions excludes those reinstated lapses.

  • Grant expiry alignment: Option expiryDate must be on or after the grant's start date (same-day expiry is permitted). Invite creation and grant edits enforce this guardrail so instruments never expire before they legally exist. If administrators try to capture an expiry that predates the grant, the platform blocks the submission and surfaces a clear error instructing them to choose a later (or equal) expiry date.
  • SARS Valuation Freshness: Exercises and discounted grants rely on the latest valuation on file. If the valuation is older than 183 days, both discounted grants and exercises are blocked unless an administrator records an explicit override. Important: Valuation staleness is measured from the current processing time (when the exercise or grant is being processed), not from historical event dates like vesting dates. This ensures fresh valuations are used even when processing delayed vesting events or backdated grants, preventing stale valuations from being applied to current transactions.
    • Override procedure:
      1. Obtain a board resolution approving reliance on the stale valuation. The resolution must be approved by the directors and minuted by the company secretary (or the designated compliance officer where no secretary is recorded).
      2. Record the approval by generating or uploading the signed resolution via Dashboard → Documents → Compliance → Board Resolution so the override is stored alongside the valuation and audit history.
      3. When editing a grant or processing an exercise against a stale valuation, tick the SARS valuation override confirmation so the acknowledgement (confirmStaleValuation: true) is recorded in the audit trail and confirmation email. When no valuation exists, capture the board approval metadata without the stale confirmation flag—the override proceeds once the supporting details are supplied.
      4. Attach the signed board minute or resolution to the override submission. Capsense blocks the exercise until a document URL is provided so SARS reviewers can trace the acknowledgement back to the supporting evidence.
    • When no valuation exists (for example, immediately after incorporation) or a stale valuation is reused to discount an exercise price, the grant edit workflow enforces entry of the board meeting date, approval reference, and fair value per share. Submissions without those details are rejected, and the stored grant now records the override metadata so SARS audits can be satisfied later.
  • Future-dated valuations: If the latest valuation date falls after the grant or exercise effective date, Capsense treats the quote as unavailable and requires an admin override. When you proceed with that override, the exercise dialog blocks submission until an administrator acknowledges the “valuation date occurs after this transaction” warning so the audit trail captures that you knowingly relied on board-approved pricing instead of the future-dated valuation.
  • Late board minutes: When the override’s board approval date is recorded after the grant or exercise effective date, Capsense surfaces a compliance warning and blocks submission until an administrator acknowledges that the board minute post-dates the transaction. This acknowledgement proves that management accepted the timing risk while still attaching the signed minute to the override.
  • Price variance acknowledgement: If the override market price differs from the board-approved fair value per share, administrators must acknowledge the variance before the exercise can proceed. The acknowledgement captures that the board-approved FMV was intentionally adjusted and keeps the override trail auditable for SARS.
  • Guardrails: Capsense refuses valuations dated after the grant or exercise effective date. Future-dated quotes are treated as unavailable, forcing administrators to either capture a compliant valuation (dated on or before the transaction) or record a manual override with the correct board-approved price. When board approval minutes are captured after the effective date, the override raises a compliance warning—administrators must either correct the meeting date or explicitly acknowledge the risk before the exercise can proceed.
  • Fair Market Value Capture: When no SARS valuation exists the member onboarding UI now flags the missing FMV, requires administrators to enter the board-approved exercise price manually, and reminds them to retain the supporting board resolution instead of deriving a nominal value from share capital.
  • Market Price on Exercise: The platform calculates the market price from the latest valuation by default. When administrators invoke the manual override, they must supply the board-approved fair market value and justification; members cannot self-submit exercises.
  • Exercise Share Class Configuration: Exercises require the scheme's exerciseShareClassId to be configured during ESOP setup. If not configured, exercise requests will be rejected with an error prompting the administrator to configure the share class via ESOP Setup or Company Configuration. There is no automatic fallback to a default share class—the configuration must be explicit to ensure proper tracking of which share class receives exercised shares. This ensures administrators make deliberate decisions about share class structure and prevents exercises from being issued to an unintended share class. Configure via Dashboard → ESOP Setup → Exercise Share Class or /api/schemes/[schemeId]/exercise-share-class.
  • Share Authorization Hierarchy: The platform enforces a hierarchical authorized share structure where company-wide authorized shares (set in Company Configuration) serves as the ceiling, and individual share class authorizations (set in Cap Table → Share Classes) represent allocations of that ceiling. The sum of all ShareClass.authorizedShares must not exceed Company.totalShares (MOI limit). This validation is enforced at both the API level (/api/company/share-classes POST and PUT endpoints) and surfaced as a real-time warning in the cap table UI when the sum exceeds the company total. The configuration page shows allocation status (e.g., "800,000 of 1,000,000 allocated (80%)") to help administrators track how the MOI ceiling is distributed across share classes. When creating or updating a share class would cause the total to exceed the company-wide limit, the API returns a detailed error message showing current allocation, the new class amount, and the excess, directing administrators to increase the company-wide authorized shares first. This prevents invalid configurations that would violate MOI limits and ensures cap table calculations remain accurate for dilution analysis and compliance reporting.

  • Backdated Vesting Policy: The API allows vestingStartDate to be earlier than the grantDate to align vesting with an employment start date or probation end. This can cause immediate vesting upon acceptance (e.g., a 12‑month cliff may elapse instantly if the backdate crosses the cliff). Admin screens show the calculated vesting outcome before saving. If you prefer to prohibit or warn on aggressive backdating, set internal policy and review the previewed vested amounts prior to submission. Future guardrails may include optional warnings when backdating exceeds a configurable threshold.

  • AI Document Templates: All AI-generated documents start from professionally-structured baseline templates (TypeScript-based) that include South African legal compliance requirements (Companies Act Section 97, Income Tax Act Section 8C, CIPC forms). AI agents refine templates with actual company data rather than generating from scratch, ensuring consistency and compliance. Templates include 50+ placeholders that are automatically filled from the company's configuration, scheme settings, grant details, and board information. The template registry (lib/document-templates/index.ts) provides access to all 6 document types: Scheme Rules, Offer Letter, Acceptance Form, Board Resolution, Compliance Certificate (CoR46.2), and Annual Report. Each template maintains a structured section hierarchy with required and optional sections, validated through unit tests to ensure completeness and legal accuracy.
  • Document AI Validation: AI-generated documents pass through 5-stage validation: (1) Drafting - loads baseline template and fills placeholders with company data from database queries, (2) Personalization - adds company-specific context and adjusts language for readability, (3) Validation - checks structural completeness and data consistency, (4) Compliance - verifies South African legal requirements including proper references to Companies Act Section 97, Income Tax Act Section 8C, and CIPC filing forms, (5) QA - performs final quality checks including grammar, formatting, and professional presentation. All documents require legal counsel review before use - AI generation creates drafts, not final legal instruments. Feature requires Enterprise plan (feature gate: ai_docs). The system supports OpenAI (gpt-5-2025-08-07) as primary provider with automatic fallback to Anthropic Claude (claude-sonnet-4-20250514) when OpenAI is unavailable. Documents are generated in dual formats (PDF for final distribution, DOCX for legal review) and stored in S3 with audit trail logging.
  • Document Legal Compliance: All AI-generated documents reference applicable South African legislation and regulatory requirements. Scheme Rules include Companies Act 2008 Section 97 (employee share scheme approval requirements), board and shareholder approval thresholds, and implementation procedures. Tax-related documents (Scheme Rules, Offer Letters, Annual Reports) include Income Tax Act Section 8C references explaining ESOP tax treatment, with explicit disclosures about tax vesting timing based on RESTRICTED (exit-only exercise - tax deferred until restrictions lift) vs UNRESTRICTED (anytime exercise - tax due at internal vesting) scheme classification. The Compliance Certificate template follows CIPC Form CoR46.2 structure for annual share scheme filings, including company registration details, scheme authorization information, annual activity metrics, and compliance officer attestation. Board Resolution templates include proper legal authority references, recitals explaining context, numbered resolutions, and director signature sections. All templates maintain professional legal tone and include disclaimers requiring qualified legal counsel review before final use.
  • Company Secretary Designation: At least one board member must be designated as Company Secretary for proper corporate governance and compliance. This requirement ensures that board resolutions, ESOP documentation, and CIPC filings have proper authority and legal validity under the South African Companies Act Section 97. The setup wizard enforces this validation before scheme activation (lib/validations.ts), blocking setup submissions until a secretary is designated. The secretary role is tracked via the isSecretary boolean field on the BoardMember model. When generating board resolutions and compliance documents, the system identifies the secretary for proper attestation and signature authority. If no secretary is explicitly designated, document generation and certain governance workflows may be blocked or require manual override.
  • Document Soft Delete (Archive): Documents use soft delete (archival) instead of permanent deletion to preserve compliance audit trails and enable recovery. When an admin archives a document, the system sets Document.deletedAt to the current timestamp and records a DOCUMENT_DELETED audit action with operation 'archived'. Archived documents are excluded from default queries (deletedAt: null) but can be viewed by toggling the "Show Archived" filter in Document Management. Restoring an archived document clears the deletedAt timestamp (sets to null) and logs a DOCUMENT_GENERATED audit action with operation 'restored'. The deletedAt field is indexed for efficient filtering. Soft delete is preferred for compliance (legal/regulatory requirements to retain document history), audit trail completeness, recovery from accidental deletion, document lifecycle analytics, and preventing permanent data loss. API endpoints enforce that documents cannot be archived twice (deletedAt already set) and cannot be restored if not archived (deletedAt is null). All archive/restore operations are COMPANY_ADMIN or SUPERADMIN only. Implementation: DELETE /api/documents/[documentId] (archive), PATCH /api/documents/[documentId] (restore).
  • Document Signature Reminders: Admins can send reminder emails to signers with pending signature requests via the Document Management interface. The reminder system (POST /api/documents/[documentId]/send-reminder) queries all PENDING signature requests for the document and sends individualized reminder emails to each pending signer. Each email includes the document name, company name, magic link to the signature page (/sign/{token}), expiry date warning, and contact information. After sending, the system updates DocumentSignatureRequest.lastReminderSentAt to the current timestamp to track reminder frequency. The audit trail logs a DOCUMENT_GENERATED action with operation 'signature_reminder_sent', recipient count, and recipient details (name/email). Best practices: Wait 2-3 days between reminders to avoid spam, send first reminder when 50% of validity period has elapsed, send final reminder 1-2 days before expiry. Reminders are only sent to pending signers (not already signed), and the system returns an error if no pending requests exist. Implementation: /app/api/documents/[documentId]/send-reminder/route.ts.
  • Document Signature Cancellation: Admins can cancel all pending signature requests for a document when content needs revision, employee leaves before signing, board resolution is superseded, or workflow is no longer needed. The cancellation endpoint (POST /api/documents/[documentId]/cancel-signature) updates all PENDING signature requests to REJECTED status and updates the parent document's signatureStatus to REJECTED. This action is irreversible—signers cannot complete signatures after cancellation and their magic links become invalid. The audit trail logs a DOCUMENT_DELETED action with operation 'signature_requests_cancelled', cancelled count, and recipient details. The system returns an error if no pending requests exist to cancel. Note: The API currently cancels all pending requests for a document; per-signer cancellation is not supported. Use cases include document regeneration (content errors found), terminated employees (offer no longer valid), superseded resolutions (new version generated), or abandoned workflows. COMPANY_ADMIN or SUPERADMIN authorization required. Implementation: /app/api/documents/[documentId]/cancel-signature/route.ts.
  • Document Management Filtering: The Document Management UI (/dashboard/documents/management) provides comprehensive filtering to help admins track documents, monitor signature workflows, and manage lifecycles. Filters include: (1) Document Type - filter by SCHEME_RULES, OFFER_LETTER, ACCEPTANCE_FORM, BOARD_RESOLUTION, COMPLIANCE_CERTIFICATE, or ANNUAL_REPORT, (2) Signature Status - filter by NO_SIGNATURE (no workflow), PENDING (awaiting signatures), SIGNED (completed), EXPIRED (links expired), or REJECTED (cancelled/declined), (3) Search - case-insensitive name search with partial matching, (4) Show Archived - toggle to view archived documents (exclusive with active view). Filters combine with AND logic (e.g., "Offer Letters" + "Pending Signature" shows only pending offer letters). The signature status filter uses multi-signer awareness—documents with multiple signers show overall status based on priority: all SIGNED → SIGNED status, any EXPIRED → EXPIRED status, any REJECTED → REJECTED status, any PENDING → PENDING status. Pagination supports 50 documents per page with Previous/Next navigation. All queries are company-scoped to prevent cross-company access. Implementation: GET /api/documents/management with query parameters type, signatureStatus, search, showArchived, page, limit.
  • Board Approval Workflow: All new grants require board approval via electronic signatures before members receive offer letters. When a grant is created, it enters PENDING_BOARD_APPROVAL status and the system auto-generates a board resolution document. All active board members receive signature requests via magic links. Once all required signatures are collected, the grant transitions to AWAITING_ACCEPTANCE_SIGNATURE status and the system generates the member offer letter. The offer letter is then sent to the member, transitioning the grant to OFFERED status. When the member signs the offer letter, the grant becomes ACTIVE. This workflow ensures proper governance approvals are collected and documented before equity commitments are made to employees. The board resolution template includes grant details, vesting terms, and legal authorization references. Electronic signatures use SHA-256 document hashing for integrity verification and token-based magic links for secure access. All signatures are timestamped and stored in the audit trail for compliance purposes.