Licenciamento

Capacidades, níveis de licença e o serviço de licença

Esta página é a referência em tempo de execução de como uma licença molda o comportamento do Doconut: o que cada estado de licença permite, como as capacidades são concedidas e como inspecionar tudo isso a partir do código. (Para carregar uma licença, veja Introdução → Configuração de Licença.)

Estados da licença e o que eles fazem

EstadoAbre documentos?Marca d'águaCapacidades
Licença completa (paga) (dentro da sua janela de assinatura/atualização)SimNenhumaAs adquiridas (Has* flags)
Licença temporária (Desenvolvedor/NFR — a licença de avaliação, antes da data de expiração)SimNenhumaTodas — concessão total (o funil de avaliação)
Expirada (uma licença temporária após sua data de expiração, ou uma assinatura paga após sua data de renovação)SimMarca d'água de avaliaçãoNenhuma concedida
Nenhum arquivo de licençaSimMarca d'água de avaliaçãoNenhuma concedida
Encontrada mas rejeitada (assinatura inválida, adulterada, na lista negra, ou uma build mais nova que a janela de versão da licença)Não — LicenseException em cada abertura

Duas consequências que vale a pena internalizar:

  • Uma licença ausente não é uma licença temporária. Sem arquivo de licença, as páginas são renderizadas com marca d'água e nenhuma capacidade (pesquisa, anotação, plugins) está ativa. A experiência completa, sem marca d'água, requer uma Licença temporária (obtenha uma).
  • Só uma licença rejeitada bloqueia a abertura. O vencimento de calendário/assinatura regride para renderização com marca d'água; mas implantar uma build mais nova que a janela de versão da licença é rejeitado e falha rapidamente com um LicenseException, então você a captura no deploy — não enviando silenciosamente saída com marca d'água. Essa exceção (de OpenDocumentAsync) traz o motivo de License.RejectionMessage.

Capacidades

Doconut controla funcionalidades opcionais por capacidade. Hoje são os plugins opcionais Converter e DICOM, além dos recursos embutidos Search e Annotation, cada um concedido pela sua licença. O visualizador base não é uma capacidade — é o pré-requisito, exposto como IsViewerLicensed:

csharp
bool viewerLicensed = lic.IsViewerLicensed; // non-TRIAL license present AND covering this build's version

O único ponto de verificação que todo o pipeline usa é IsCapabilityGranted:

csharp
bool searchGranted = lic.IsCapabilityGranted(LicenseCapability.Search);

Sua lógica, literalmente da implementação: uma licença temporária ativa (não expirada) concede todas as capacidades — incluindo capacidades que ainda não têm uma flag de compra dedicada; uma licença comprada real concede exatamente suas flags Has* e tem negação padrão para qualquer coisa não mapeada. (Um arquivo legado do tipo TRIAL não é um direito — ele é tratado como não licenciado: marca d'água, nada concedido.)

Licenças temporárias

Pesquisa e Anotação normais usam suas capacidades existentes diretamente.

Licenças temporárias (Desenvolvedor/NFR) são marcadas por uma tag ExpiryNote e possuem uma data de expiração fixa:

MembroSignificado
IsTemporaryUma tag ExpiryNote está presente (a detecção é pela presença da tag — nunca compare o texto da nota, é dinâmico)
ExpiryNoteTexto informativo embutido na licença
LicenseExpiryA data de expiração fixa (DateTime?)

A semântica de expiração difere por nível: uma licença temporária expira apenas na data LicenseExpiry (sua janela de assinatura é ignorada; uma licença temporária sem data é tratada como expirada, por segurança). Todas as outras licenças expiram na data da janela de assinatura/atualização.

Referência IDoconutLicenseService

Injete IDoconutLicenseService (namespace Doconut.Core.Interfaces; registrado como singleton — a licença é analisada uma vez na inicialização):

MembroSignificado
LicenseInstantâneo completo DoconutLicenseInfo (abaixo)
IsTrialUm arquivo legado do tipo TRIAL (tratado como não licenciado — não é um direito)
IsTemporary / ExpiryNote / LicenseExpiryMarcadores de licença temporária
IsExpiredExpirada conforme as regras de nível acima
IsVersionValidEsta build está dentro da janela de suporte da licença
IsViewerLicensedArquivo não-TRIAL encontrado e versão coberta — pré-requisito base
IsCapabilityGranted(cap)O único ponto de verificação de capacidade
HasSearch HasAnnotation HasConverter HasDicomFlags de compra por capacidade — use IsCapabilityGranted para a resposta consciente de temporárias
IsValidForDomain(host)Cobertura de host; licenças V4 usam o curinga *.*
LicenseRejectionReasonNão vazio ⇒ a abertura é bloqueada com esta mensagem

DoconutLicenseInfo expõe o instantâneo amigável para exibição em painéis de administração: Owner, Email, LicenseType, Domain, IsLicenseFileFound, IsVersionValid, IsTrial, IsExpired, as flags Has*, os campos de licença temporária e RejectionMessage.

csharp
// Feature-flag your UI from the same source of truth the SDK uses
app.MapGet("/api/features", (IDoconutLicenseService lic) => Results.Ok(new
{
    viewer     = lic.IsViewerLicensed || lic.IsTemporary,
    search     = lic.IsCapabilityGranted(LicenseCapability.Search),
    annotation = lic.IsCapabilityGranted(LicenseCapability.Annotation),
    conversion = lic.HasConverter,
    dicom      = lic.HasDicom,
}));

Verificação de saúde

AddDoconut() registra uma verificação de saúde "doconut" que relata o estado da licença/expiração através do mecanismo padrão do ASP.NET Core:

csharp
app.MapHealthChecks("/health");

Integre-a ao seu monitoramento e uma assinatura que está expirando se torna um alerta em vez de um ticket de suporte.

Atualizações de versão

Uma licença cobre uma janela de versão. Atualizar o pacote NuGet para uma build mais nova que essa janela torna a licença inválida para esta build: IsVersionValid passa a false e a abertura é bloqueada com um LicenseException (o motivo está em License.RejectionMessage) — falha rápida deliberada, para que uma build obsoleta ou não licenciada seja detectada no deploy em vez de marcar silenciosamente a produção com marca d'água. Renove a assinatura, substitua o .lic e reinicie a aplicação para que AddDoconut() carregue a nova licença.

Esta página foi útil?