Changelog
O que há de novo.
Cada melhoria para a plataforma, como ele envia.
· kamo-shared-library
Períodos de pagamento, pausas, prémios, contas de trabalho, acréscimos, exportação
Bate o esquema de salário-e-hora restante em uma mudança de lib-compartido para o todo o domínio terras em um único KamoInitializer executar em vez de uma migração por fase. Entidades: períodos de pagamento com colunas de congelamento regra-versão, ganhando linhas, quebra regras e violações, contas trabalhistas e segmentos de trabalho, políticas de exercício, saldos e registros, casos de licença, lotes de exportação, ocorrências de atendimento. Quatro motores puros, 51 testes: BreakEvaluator – nunca deduz automaticamente um almoço, porque uma refeição auto-deduzida o empregador não pode provar que era duty-free. Prémios São os WAGES (Naranjo), por isso eles fluem em ganhos em vez de um relatório. Uma Prémio por CATEGORIA por dia (UPS v. Tribunal Superior): duas refeições perdidas devem Um, uma refeição perdida e um descanso perdido devem dois. Uma renúncia de refeição é honrada apenas Quando o estatuto o permite — o trabalhador não pode consentir fora dele. Descanso estão sem golpes, por isso o silêncio no atestado nunca é marcado como uma violação. RegularRateCalculator — horas extras é devido sobre a taxa REGULAR, não a base taxa. 778.115 média ponderada, 778.209 horas extras retroactivas sobre Bónus não discricionários, 778.216/218 exclusões e prémio a tempo parcial: tempo direto já está no total, então horas extras acrescenta 0,5x, não 1,5x. AccrualEngine — um teto pára de accrual sem eliminar o equilíbrio, o reporte é tampado separadamente do teto, e uma dedução que quebraria o chão lança em vez de aprovar silenciosamente meio dia de folga. PayPeriodCalendar — gerado, não inserido à mão, e verificarContíguo recusa uma diferença (trabalho que não pertence a nenhum período, nunca pago) ou uma sobreposição (pago duas vezes).
· kamo-shared-library
Modelo de exceção e detector
Torna o bloqueioExceptions portão real. Até agora, a tabela de transição lê contar que nada escreveu, então cada cartão parecia limpo e 'um soco faltando é Nunca pago como zero foi um comentário em vez de um controle. A distinção BLOCKING é todo o ponto da taxonomia: uma mudança aberta, e Punch inigualável e uma finalização provisória não comprovada, porque fechar-se sobre eles afirma algo que ninguém pode ficar para trás. Uma falha geofence e um clock skew são Advisory e nunca bloquear -- recusando-se a gravar ou finalizar o tempo que foi realmente trabalhado é a violação salarial exata que este sistema impede. O detector reporta e nunca repara. Todas as formas de adivinhar um turno fechado está errado: deixando-o aberto acumula horas absurdas, auto-fechando sub-relatórios, uma tampa inventa uma figura que ninguém testemunhou. Em vez disso, torna-se uma excepção. Idempotente pela construção através da restrição única (membro, data, tipo) -- duplicados iria inflar a contagem e tornar um cartão de tempo infinalizável por uma razão Ninguém conseguiu encontrar.
· kamo-internal
Confirmar antes de interromper um pagamento recorrente
Ambas as ações de cancelamento — sede de um membro e plano de um gerente de grupo — perguntam agora primeiro, nomear a capa de data corre para e, para um grupo, quantas pessoas mantêm assentos até lá. Deliberadamente não a Confirmação compartilhadaDialog. Essa requer digitar DESTROY, DELETE, REMOVER ou ERASE antes de seu botão permite, o que é certo para o Supressão irreversível. A anulação não é irreversível nem destrutivo: não se perdem dados, o acesso continua até ao fim do período pago, e Você pode assinar novamente quando quiser. Uma luva tipo-a-palavra na frente de parar um pagamento é fricção na única ação que um cliente é de forma inequívoca direito de tomar facilmente. Nenhum dos botões diz "Cancelar". Numa janela sobre cancelamento, essa palavra significa ambos "abandonar este diálogo" e "cancelar minha assinatura" e não pode ser lido de forma confiável como ambos os botões nomeiam o seu resultado: "Mantenha o meu plano" e "Pare o futuro pagamentos".
· BillingService
Transportar a data de renovação da cobertura e das cargas úteis do grupo
Ambas as superfícies agora reportam o PeriodEnd atual e o cancelamentoAtPeriodEnd. A data é o que uma confirmação de cancelamento realmente precisa dizer — "você manter seu assento até o fim do período" é garantia no resumo, "você manter seu assento até 14 de março" é a garantia de que alguém pode agir.
· kamo-internal
Diz às pessoas quando uma conta precisa delas, e deixa-as parar de pagar
Um banner na página inicial quando um pagamento esta pessoa é responsável por tem falhou, ligando directamente à página de facturação. Até agora um pagamento falhado apareceu apenas como aplicações que deixaram de ser abertas — restrição sem explicação, que lê como software quebrado em vez de uma fatura não paga. Criados apenas para notas que podem agir sobre: seu próprio assento, e grupos que gerem. Ele renderiza Nada quando não há nada a dever. Cancelar agora é visível onde a pessoa pode ver quem paga: um "Cancelar automático pagamentos" ação em seu próprio assento, com o texto de ajuda dizendo claramente que eles manter o lugar até ao final do período que já pagaram. A confirmação nomeia a data, porque o medo ao pressionar esse botão é que O acesso para imediatamente. O interruptor "Deixe os auto-pagadores escolherem o seu próprio plano" desapareceu. O plano pertence a a organização e todos os que pagam dentro dela — individualmente ou em grupo — compra o mesmo plano. O painel de grupo agora declara o plano da organização em vez do que oferecer uma escolha.
· BillingService
Um plano por organização, um teto de 25 lugares Enterprise, e uma maneira de parar de pagar
O plano é agora uma decisão de nível de organização e nada mais pode sobrepujá-lo. Deixar um auto-pagador ou um gerente de grupo escolher suas próprias leituras como uma bondade e é um erro de correcção: * * * * * * * * Responde a esta org ter este aplicativo" por OR-ing em cada assinatura ao vivo segmentando o org, então um pessoa em um assento escolhendo um plano superior comutado os aplicativos desse plano ligado para o toda a organização. Prender cada pagador para o plano da organização faz que a SO inofensivas — as assinaturas nomeiam todos o mesmo plano, por isso, consoante o que ganhar respostas idênticamente. OrgPlanService lê o plano da mesma assinatura dos Planos e O console de faturamento chama "seu plano", então a regra e a tela não podem discordar. Empresa é necessária acima de 25 lugares, contados em toda a organização e cada Grupo de cobrança. Contar por pagador teria feito a divisão em grupos uma maneira de Comprem cinquenta lugares vinte e cinco de cada vez. Uma edição exclui a sua própria subscrição o encolhimento é medido em relação ao novo tamanho, não o antigo. GET /self/alerts dirige um banner home-page. Acesso restrito sem explicação é a pior versão deste produto – aplicativos param de abrir e ninguém diz porquê, ou que a pessoa que lê é quem pode consertá-lo. Só angariado para contas membro é responsável por: seu próprio assento e grupos que eles gerenciam. A dizer a alguém o cartão de sua organização falhou quando eles não podem pagar é ruído, e ruído é como os banners deixam de ser lidos. POST /self/seat/cancel pára o pagamento automático em um assento que alguém comprou eles mesmos. Sempre no fim do período: pagaram pelo período em curso, e cancelar imediatamente retiraria esse acesso sem reembolsar nada, uma vez que Esse caminho pede ao Stripe que não proracione. Dois bugs em cancel() encontrados enquanto fiação: - Foi um silêncio para a comissão e julgamento. O corpo inteiro senta-se atrás de um stripeAsscriptionId null check, então uma assinatura comped ou de teste retornada 200 com a linha ainda ativa — o ouvinte disse que funcionou quando nada mudou. Agora recusa-se e diz porquê. - imediato=verdadeiro permanece perigoso e não é deliberadamente exposto: define CANCELED então chama backToFree, que define ACTIVE / FREE com assentoConte 1, assim uma org de 25 lugares manteria uma pessoa que trabalha e dizer 24 o seu lugar foi cortado para uma razão de contagem de lugares que nunca aconteceu. feedture.fail-open é definido falso aqui para coincidir com o SecurityService, que serve /api/security/features e é o que a tela Apps & features lê. Dois serviços responder à mesma questão de direito de forma diferente é pior do que qualquer uma das respostas. Seguro verificado: todos os seis planos ativos possuem uma linha explícita para todos os 21 serviços Tipos, então nada anteriormente concedido está sendo negado.
· SecurityService
Relé de nível de aprovação com função resolvida a partir de direitos
O PAPEL DECISOU AQUI, dos direitos do interlocutor e sua relação com o sujeito -- nunca do corpo de solicitação. Um corpo que poderia nomear seu próprio papel Deixaria qualquer um alegar ser folha de pagamento. Precedência: PAYROLL (mais amplo, edita em qualquer estado), então MANAGER, em seguida, EMPREGO para o seu próprio recorde. Ser o gerente instantâneo do sujeito conta por conta própria -- um gerente de linha que aprova seu próprio relatório é o caso comum e não deve precisa de um direito de org-wide; o direito existe para todos os outros que comentam. isManagerOf fails CLOSED: uma linha de relatórios não resolvível não é autoridade.
· kamo-shared-library
APROVAÇÃO TIMECARD AJUSTAMENTOS (197) e FINALIZAÇÃO PAY PERÍODOS (198)
Dividir assim a separação dos deveres é expressível: quem aprova um cartão de tempo não é automaticamente, quem pode fechar um período de pagamento sobre ele. CARREIRAS DE GESTÃO (183) fica o portão do módulo e não é de propósito nenhum. A inscrição ainda não é um direito - é um fato de emprego persistente. Direito vazamentos ON através de quatro comportamentos enviados e desaparece de um membro TERMINADO exactamente quando a HR deve apresentar o seu cartão de ponto final. Deliberadamente ausente de NEW RIGHT SEEDS: que carrega uma subvenção existente para a frente, e estes portões uma capacidade que ninguém tinha. Adicionar um direito só precisa de um SecurityService reiniciou -- nenhum passe KamoInitializer, nenhum DDL. Ids fixados por um teste, porque o id é o que member rights applied lojas.
· kamo-shared-library
A máquina de estado de nível de aprovação
O empregado submete -> o gerente aprova -> a folha de pagamento fecha, por decisão do proprietário. Quatro regras, aplicadas em uma tabela de transição pura e fixadas por 25 testes: 1. Um gerente não pode aprovar até que o empregado tenha apresentado. A apresentação é Afirmação do próprio empregado de que as horas são suas e completas; aprovar sem aprovar nada que ninguém tenha atestado. 2. A aprovação do gerente bloqueia o empregado fora de edições adicionais. 3. Um gerente PODE agir em nome - submeter ou aprovar - e que é o único rota sancionada após a regra 1. Requer uma razão escrita, e a linha registra tanto o gerente que clicou como o empregado que defendeu. 4. Payroll pode editar em qualquer estado, incluindo bloqueado, sempre com uma razão. Correções após o encerramento são rotina e legalmente necessárias; proibindo-os apenas move a edição para fora da trilha de auditoria. Segregação de deveres vive na tabela de transição, não na nomeação de papéis: ninguém aprova o seu próprio cartão de ponto, e um gerente é empregado de alguém também. Cascatas desaprovadoras de PAYROLL LOCKED até SUBMITADO, porque A retirada de uma homologação invalida a fechadura que nela foi construída. As homologações são abrangidas por um RANGE DATE, pelo que uma aprovação a meio do período sobrevive a uma aprovação posterior editar fora do seu âmbito em vez de silenciosamente cobrir o trabalho que nunca viu.
· kamo-internal
Página do cartão de tempo dos membros e da página de configurações dos cartões de tempo HRS
A guia do membro é APENAS AUTO-SERVIÇO e fechado na identidade, exatamente como conformidade legal: os seus objectivos não tomam nenhum ID de membro, por isso é estruturalmente incapaz de mostrar as horas de outra pessoa. checkRight é inutilizável aqui -- ele retorna verdadeiro para tudo sob o modo de deus, e a página própria canViewOtherMemberAccount ORs em direitos não relacionados, incluindo **************************** A FC que atinge o cartão de tempo de uma pessoa específica é uma superfície diferente em /hr/attendence, atribuída ao ator de RH. Colocado antes de planos-billing para que fique no grupo da aba esquerda -- qualquer coisa depois herda o alinhamento da aba Direito ml: 'auto'. A página HRS ganha sua primeira guia real ao lado do ComingSoonTab, registrado em SETTINGS MENU como o teste de cobertura requer em ambas as direções. Ambas as páginas eles mesmos em cada caminho de retorno; SettingsView, TabPanel e o movimento div tudo fornecimento zero.
· kamo-internal
/hr/assinatura e o controle do relógio NavTop
Substitui o corpo HrTabPlaceholder. A rota, entrada HR TABS, GESTÃO TIMECARDS gate e tab i18n chaves já existiam; nada aqui registra nada. As horas de roster são derivadas do servidor do registro imutável de socos em cada leitura em vez de ser mantido como um total em execução, então um soco corrigido mostra imediatamente e um erro produz um número errado uma vez em vez de complicar. O controle do relógio é cromado fixo ao lado de Legal & Compliance, não um NAV REGISTRY entrada: o registo não pode expressar uma posição entre dois controlos fixos, o seu O distintivoKey é código morto, e cada entrada de registro é arrastável e inpinnable -- Um relógio de conformidade não deve ser algo que alguém possa esconder de si mesmo. Ele porta na matrícula PERSISTED, nunca checkRight, que retorna verdadeiro para todos os direitos sob o modo deus e mostraria um relógio em cada org um operador visitada. timecardControlAplicações é compartilhada pelo controle e sua votação para tanto ficar quietos juntos -- duas cópias desse drif predicado, e o modo de falha é um botão oculto cuja busca corre para sempre. O estado do relógio é um QUATRO sinal independente: não presença (60s batimento cardíaco, 300s TTL), e não disponibilidade status, que é auto-set para AWAY na saída e portões chumbo e roteamento de suporte. Por agora, só para pesquisas com 60 andares. O relé STOMP chega com o MediaService mudança; núcleo NATS é unstreamed e lossy assim que a semente REST é obrigatória de qualquer maneira.
· kamo-shared-library
Acessório de data-relógio no repositório de socos
Cada instante de soco vem do DB, nunca o JVM: pods reiniciar e nó clocks skew, e um registro salarial cuja ordem depende de qual pod respondeu é Não é um recorde. CAST padrão SQL, porque um :: elenco é silenciosamente mutilado -- Hibernate lê ':' como prefixo de parâmetro-nomeado e vira now()::timestamp into :timestamp.
· kamo-internal
Rota BFF para /api/security/timecards
TimecardService é ClusterIP sem entrada, então sem esta rota toda recurso 404s no navegador, enquanto cada serviço é saudável e cada construção é verde -- a falha exata que já aconteceu duas vezes nesta plataforma. Não há autorização aqui, deliberadamente: esta camada é de transporte, e um meio-check Convidaria a crença de que é um controle. forwardToApi possui a string de consulta. Um 204 é retornado como 204 em vez de ser passado através de .json(), que joga.
· SecurityService
Retransmissão do serviço de segurança para o serviço de cartão de tempo
O limite da autorização. TimecardService detém os dados eo motor, mas não sessão; isso mantém a sessão e decide quem pode fazer o que, em seguida, retransmite. A Portanto, o motor nunca pode ser alcançado sem passar por aqui. SecurityService executa anyRequest().permitAll() com auth per-handler laminada à mão, Então todos os métodos se abrem com um guarda que retorna não null para recusar. Auto-serviço endpoints tomam NENHUM membro id em tudo -- o membro vem da sessão, fazendo eles estruturalmente incapazes de agir em outra pessoa. Endpoints de FC ligados GESTÃO DE TEMÉCIOS (183). A inscrição é respondida da linha de emprego persistente em vez de um direito, por isso um operador de modo-deus não aparece matriculado em cada org que olha. SUDO MEMBER ID é realizado através de: isSelf() upstream trata uma personificada sessão como o membro alvo, então sem ele um soco de imitador seria registado como próprio do empregado. timecard.service.url está definido EXPLICAMENTE no mapa de configuração. comissão.serviço.url é definido em nenhum lugar e produção depende de um literal em Java, que um Serviço renomear iria quebrar em tempo de execução sem nada em configuração para grep.
· kamo-shared-library
Dia de trabalho de baldes, fase 2 do gasoduto
Os intervalos resolvidos tornam-se segundos por data de negócio, prontos para o alocador. Um intervalo é SPLIT em cada limite do dia de trabalho que cruza: um turno 22:00-06:00 menos de meia-noite é 2 horas em um encontro e 6 no próximo. Atribuir todo o período até sua data de início faz horas extras diárias e a regra do sétimo dia errado para cada trabalhador noturno. Esta é deliberadamente uma atribuição diferente do businessDate persistiu O soco. O ponche tem uma data -- para avaliação da refeição/descanso, a exceção fila e o que o empregado vê como seu turno -- enquanto precisa contar horas extras horas repartidas através dos dias de trabalho e semanas de trabalho em que eles realmente caiu. Ambos são corretos, ambos são necessários, e conflitá-los é a armadilha. Uma mudança que atravessa o limite da WORKWEEK contribui igualmente para duas semanas» total de horas extras; contando tudo em qualquer um é errado para ambos. Acumule em segundos. Os testes cobrem ambas as transições do horário, 50 horas E bate de ponta a ponta através de alocação para uma semana na Califórnia.
· InitializerService
Registo de KI e migração de esquemas
As tabelas vêm do ddl-auto; este corredor fornece apenas o que Hibernate não pode -- os índices parciais únicos sobre uma atribuição primária aberta e uma taxa de pagamento aberta janela, e o REVOKE que é o banco de dados metade de app-only. @Order(0) então ele pousa antes de qualquer mais tarde corredor JPA SELECT, com uma repetição 4001 porque Yugabyte faz mudança de esquema online e uma instrução emitida enquanto ddl-auto Ainda está se estabelecendo perde a corrida. Registra com.kamo.z.shared.hr.timecard em @EnableJpaRepositórios -- essa lista é um array explícito enquanto @EntityScan é wildcard, e omitindo um pacote aborta o contexto para que o NO execute enquanto a compilação ainda relata o sucesso.
· kamo-shared-library
Limites da semana de trabalho e da jornada de trabalho
A semana de trabalho é a unidade de horas extras FLSA -- um fixo, regularmente recorrente 168 horas período - e não é o período de pagamento. Um período quinzenal contém exatamente dois semanas de trabalho; um período semestral ou mensal sempre detém fracionários, assim computação de horas extras em um período total tanto de sub-pagamentos e sobre-pagamentos e é não fixa uma vez que os períodos são exportados. A fronteira do dia de trabalho é transportada separadamente e não é necessariamente meia-noite. A 06:00 início é a correção padrão para o pessoal da noite: mantém um turno 22:00-06:00 em UM dia de trabalho em vez de dividi-lo em dois meio-dias, que é o que faz horas extraordinárias diárias e a regra do sétimo dia de trabalho para eles em tudo. Limites são tempos de relógio de parede resolvidos através do ZonedDateTime, então 06:00 estadias 06:00 num dia de 23 ou 25 horas. Testes fixar ambas as transições, e pin que um instantâneo é uma data de negócios diferente em Los Angeles e Kolkata -- por isso a zona de registro é persistida no soco em vez de derivada posteriormente.
· kamo-shared-library
Resolução do intervalo, fase 1 do gasoduto de cálculo
Os socos tornam-se pontos resolvidos. Tipos de valor puro, total e superior, em vez de entidades para que cada etapa seja fixture-testável sem contexto de persistência. Duraçãos vêm de Duration.entre em instantes, nunca parede-relógio subtração. Essa é toda a história do horário e os testes prendem-na: um turno das 22:00-06:00 é de sete horas na primavera-avançada e nona na volta. Relógios de parede subtraídos calcula 8 para ambos -- um subpagando, um sobrepagando, e em um overtime diário jurisdição a noite de 9 horas silenciosamente perde sua hora extra. Qualquer coisa imperdível volta como não resolvida em vez de adivinhada. Um não fechado turno é uma EXCEÇÃO: deixando-o aberto acumula horas absurdas, auto-fechamento em um E um boné fixo inventa um número que ninguém testemunhou. Ele nunca deve finalizar como zero - que não paga nada por um dia que foi trabalhado. As refeições são perfuradas, nunca deduzidas automaticamente. TRANSFER fecha um vão e abre o próximo sem terminar o turno, então horário da refeição e elegibilidade de turno Prosseguir através de um movimento intermédio entre centros de custos.
· kamo-shared-library
Alocador de horas extras sem piramitação com predefinições de jurisdição
As regras são os DADOS sobre a forma RequirementRule já utilizada nesta biblioteca, não ramificações de código, então Califórnia é uma linha de configuração em vez de uma reescrita. Ordem de atribuição é suporte de carga: regras diárias maior limiar-primeiro (um 13-hora O dia da AC é 1h a 2x e 4h a 1,5x, não 5h a 1,5x), em seguida, o sétimo dia consecutivo, NET semanal de horas já a um prémio diário. Este último passo é o que impede a pirâmide, e é o único motor ingénuo Omitir. Cinco dias de 10 horas na Califórnia são 10 horas premium, não 20 -- um ingênuo motor paga diariamente E semanalmente para as mesmas dez horas, e cada regra individual O teste passa enquanto passa. O alocador também afirma conservação de horas no Uma saída e atira em vez de devolver um salário errado. Predefinições: FLSA federal, Califórnia, Alasca, Nevada, Colorado.
· kamo-internal
Entregar o fuso horário org ao navegador
O modelo de organização do cliente não tinha nenhum campo de fuso horário, useFormatters e next-intl são ambos configurados sem timeZone, e chamada de backend do timezoneService 404'd -- assim, cada timestamp renderizado na zona do navegador, e do servidor durante SSR. Espelhos todos os 27 valores do TimezoneType em vez de um subconjunto: um mapa parcial é um meio espelho silencioso onde uma org não mapeada cai para a zona do navegador com Sem sinal. Mapas GMT para Europa/London, não UTC -- observa BST, tão conflitando Eles mudam um dia inteiro horas por uma hora durante metade do ano. A zona de org é apenas um retrocesso DISPLAY. Um censo de produção encontrou todas as 13 orgs em o padrão PACÍFICO intocado enquanto os membros abrangem o PACÍFICO/EASTERN/ARIZONA/UTC/ ÍNDIA, então o fuso horário do registro vem do local de trabalho.
· SecurityService
- ESTÁ BEM
timezoneService.ts chamou este endpoint desde que foi escrito e existiu em nenhum serviço Java; o cliente engoliu o 404 e resolveu para UTC. Entretanto UseFormatters e next-intl são ambos configurados sem tempoZone, então cada timestamp renderiza na zona do navegador -- e o retorno *** é o texto «GMT», que é a Europa/Londres e observa a BST. Identidade vem da sessão somente: SegurançaService é permitidaTodos com um manipulador que lê a identidade do pedido não tem nenhum controle. Registra com.kamo.z.shared.hr.timecard em @EnableJpaRepositórios. Essa lista é... um array explícito enquanto @ComponentScan/@EntityScan são wildcard, e omitindo O pacote é a causa documentada de duas implementações anteriores do CrashLooping.
· kamo-shared-library
WorkSite, a âncora da jurisdição
Local de Trabalho Nomeado, não Localização de Trabalho: TeamMember.workLocation é um existente office/remote enum e um segundo símbolo com esse nome colidiriam em cada grep. ZoneId é uma string IANA livre em vez de TimezoneType porque esse enum é 27 valores não podem cobrir um empregador multi-estado, e não é NULL porque é o única camada de zona confiável - cada org na produção assenta sobre o intocado Padrão PACÍFICO.
· kamo-shared-library
Emprego e revisões de atribuição efectivas
Os socos farão referência a um DESIGNMENT, não a um membro. É isso que faz posições simultâneas, a taxa regular média ponderada de 29 CFR 778.115, jurisdição multi-site e custo de trabalho expressível em tudo. managerMemberId é instantâneo do TeamMember.manager na hora da revisão, então um A reorganização não pode reescrever quem aprovou o quê. O localizador de lista não é deliberadamente construído sobre member rights applied: aquela consulta é TeamMember-typed, por isso omite a concessão-all org proprietários e não retorna nada para um Membro finalizado cujos direitos aplicados foram despojados -- precisamente a pessoa cujo cartão de tempo final ainda tem que produzir.
· kamo-shared-library
Taxa de pagamento efectiva, apenas em anexo
Não existia qualquer compensação de empregados nesta plataforma antes desta entidade. É necessário: horas extras é calculado contra a taxa regular FLSA, CA exige a taxa da declaração salarial, e uma exportação sem taxas dá folha de pagamento Nada para consumir. Um aumento é uma NOW ROW. Uma taxa efetiva dentro de um período exportado gera um ajuste retro, nunca uma reescrita silenciosa. Nunca exposto via /api/security/members/{id} -- esse ponto final não verifica nenhum direito em Todos, por isso colocar uma taxa nele iria vazar todos os salários da empresa.
· kamo-shared-library
Anexar apenas o registo de ponche e o evento de auditoria
Ambos servidos por interfaces de repositório NARROW, não JpaRepository: deleteAllInBatch e bulk JPQL bypass entity callbacks, então a forma da interface é o que faz Anexar-apenas real em vez de aconselhamento. Instant + IANA zona + data de negócio são todos persistentes, por isso a duração é calculada a partir de instantes e horário é correto gratuitamente -- um turno 22:00-06:00 é de 7 horas através da mola para a frente e 9 através de retrocesso, enquanto parede-relógio subtração calcula 8 para ambos. updatable=false é deliberadamente NÃO usado nas colunas de soco congeladas: Hibernate Omitiria-os silenciosamente da UPDATE em vez de falhar.
· kamo-shared-library
Resolução do fuso horário de registo
Local de trabalho de ordem da autoridade -> membro -> org -> UTC. O local de trabalho ganha porque As regras salariais e horárias seguem o local onde o trabalho é realizado. Um censo de produção desta sessão encontrou todas as 13 orgs no PACÍFICO intocado padrão e 38 de 63 membros sem fuso horário, enquanto os povoados espaço PACÍFICO, OESTE, ARIZONA, UTC e ÍNDIA -- uma extensão de 13,5 horas. O org padrão não é, portanto, uma fonte utilizável de verdade, que é por isso WorkSite.zoneId NÃO é NULL e carrega o peso. Regressa à UTC em vez da corda *** 'GMT', que é a Europa/Londres e observa BST. Uma zona inparseável cai através do local em vez de lançar: Recusar-se a resolver uma zona recusar-se-ia a registar o tempo efectivamente trabalhado.
· kamo-shared-library
Guarda de recusa de WORM partilhada
@Column(updatable=false) NÃO impõe imutabilidade -- Hibernate silenciosamente omite a coluna da UPDATE e a escrita antiga parece ter sido bem sucedida. O único guarda que trabalha é um @PreUpdate que joga.
· kamo-shared-library
Enums de domínio e resolução de versão ponto-em-tempo
Os números são todos @Enumerado(STRING) no local de chamada: ORDINAL emite um numérico intervalo de verificação contendo E, que SchemaCleanupRunner's In-list varre deliberadamente salta e que deve então ser alargado à mão sobre cada novo valor. O resolvedor resolve pela janela que CONTÉM o instante, nunca por última linha, e mantém janelas fechadas no conjunto de candidatos -- a supersessão fecha todas as janelas, menos a actual, por isso, uma consulta só de linhas abertas não devolve nada para qualquer instante histórico, quebra retro pagamento e reconstrução de auditoria. Sobreposição lança em vez de adivinhar.
· kamo-internal
Mostrar os membros que pagam pelo seu lugar, e parar de oferecer um segundo
O endpoint de cobertura enviado com chaves de tradução e nenhum componente, por isso o questioná-lo responde — quem paga o meu lugar — ainda não tinha nenhum lugar para ser perguntado. SeatCoveragePanel pergunta, e a resposta alimenta o painel de auto-pagamento ao lado: alguém cujo assento já está coberto pela sua organização ou um grupo não é mais tempo ofereceu a oportunidade de comprar outro em seu próprio cartão. Essa oferta não tinha conhecimento da cobertura existente, por isso foi mostrado a todos. O plano de um grupo também pode ser cancelado agora, o que faz um grupo com plano deletável — remover um que ainda aponta para uma assinatura ao vivo é Recusada, para que a acusação não seja orfã. Adicionar alguém que a organização já paga volta recusado em vez de silenciosamente não fazer nada, por isso o botão explica-se.
· BillingService
Deixe o plano de um grupo ser cancelado, e pare de pagar em dobro por uma pessoa
Três lacunas no último envio: Um grupo com um plano nunca poderia ser removido. delete () recusa enquanto um live assinatura existe — correto, uma vez que a linha do grupo é a única coisa apontando para A assinatura da Stripe — mas não havia forma de cancelar, pelo que a salvaguarda beco sem saída. cancelPlan () libera os assentos primeiro, então o roster não pode continuar Afirmando que as pessoas ocupam lugares que já não existem. Adicionar alguém a organização já compra um lugar para é agora recusado, a menos que TakeOver FromOrg diz o contrário. Esta é a segunda forma de cobrar duas vezes uma pessoa e nada o pegou: AssinaturaOs únicos do membro são por assinatura e ContaLicense declara nenhum. Tirar alguém de A conta da organização em um grupo é uma coisa real que um gerente faz, então é permitido — deliberadamente em vez de por acidente. BillingGroupScopeInterceptor liga cada pedido /api/billing/groups/{uid}/** Para a organização do chamador. Os manipuladores já verificam, e isto não Substituí-los; existe porque esses controlos são por pessoa e um grupo tem agora sub-recursos que gastam dinheiro. A próxima rota adicionada não herda nada a menos que algo acima aplica a regra. Deliberadamente mais estreita do que os manipuladores: isso estabelece qual organização, não quem dentro dela pode agir, de modo que os dois não podem derivam em respostas discordantes. Um ID de grupo desconhecido passa por O manipulador responde "não encontrado" ao invés de confirmar que o id existe em algum lugar.

Seu universo está esperando.
Comece gratuitamente em minutos.Adicione produtos sempre que estiver pronto — sem migração, sem novos logins.
Gratuito para sempre — não é necessário cartão de crédito