@softize/opus 28.0.0 → 29.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/bin/cli.mjs +68 -3
- package/bin/lib/copy.mjs +505 -67
- package/bin/lib/materialize.mjs +99 -1
- package/docs/adr/0028-schedules-run-actions-as-the-system-by-action-opt-in.md +1 -1
- package/docs/adr/0037-design-data-lives-outside-the-contract.md +1 -1
- package/docs/adr/0061-claude-md-imports-agents-md.md +41 -0
- package/docs/adr/README.md +2 -0
- package/docs/code-style.md +47 -8
- package/docs/protocol.md +1 -1
- package/docs/releasing.md +7 -0
- package/package.json +1 -1
- package/registry/instructions/opus.md +3 -1
- package/registry/skills/build-opus-ui/SKILL.md +5 -3
- package/registry/skills/maintain-opus-docs/SKILL.md +2 -1
- package/registry/skills/maintain-opus-docs/references/editorial-standard.md +9 -0
- package/registry/skills/maintain-opus-docs/references/evaluations.md +8 -0
- package/registry/templates/app/pnpm-workspace.yaml +1 -1
- package/src/core/system-actor.ts +1 -1
- package/src/ui/components/patterns/list.tsx +1 -1
- package/src/ui/docs/content/action-list.md +1 -1
- package/src/ui/docs/content/actions.md +1 -1
- package/src/ui/docs/content/auth.md +3 -3
- package/src/ui/docs/content/cli.md +6 -0
- package/src/ui/docs/content/communication.md +10 -8
- package/src/ui/docs/content/events.md +13 -13
- package/src/ui/docs/content/installation.md +4 -0
- package/src/ui/docs/content/log.md +1 -1
- package/src/ui/docs/content/queue.md +2 -2
- package/src/ui/docs/content/router.md +1 -1
- package/src/ui/docs/content/scheduler.md +15 -15
- package/src/ui/docs/content/testing.md +4 -4
- package/src/vite/design.ts +1 -1
|
@@ -44,7 +44,7 @@ const runtime = createRuntime({
|
|
|
44
44
|
|
|
45
45
|
// No handler: ctx.log já traz o request ID e a action, adicionados com child().
|
|
46
46
|
handler: async (ctx, input) => {
|
|
47
|
-
ctx.log.info('emitindo nota', {
|
|
47
|
+
ctx.log.info('emitindo nota', { amount: input.amount })
|
|
48
48
|
return repo.create(input)
|
|
49
49
|
}
|
|
50
50
|
```
|
|
@@ -59,11 +59,11 @@ const runtime = createRuntime({
|
|
|
59
59
|
queue,
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
-
export const
|
|
62
|
+
export const reportGenerate = bindAction(reportGenerateContract, {
|
|
63
63
|
background: { enabled: true, retry: { attempts: 3 }, progress: true },
|
|
64
64
|
handler: async (ctx, input, loaded, progress) => {
|
|
65
65
|
await progress?.report({ percent: 50, message: 'Consultando dados' })
|
|
66
|
-
return
|
|
66
|
+
return generateReport(input)
|
|
67
67
|
},
|
|
68
68
|
})
|
|
69
69
|
```
|
|
@@ -76,5 +76,5 @@ o erro de uso.
|
|
|
76
76
|
|
|
77
77
|
`navigate` espera um caminho da própria origem e não valida destinos. Quando o destino vem de fora,
|
|
78
78
|
como o `?redirect=` de um pós-login, valide-o antes de navegar: resolva com
|
|
79
|
-
`new URL(
|
|
79
|
+
`new URL(target, origin)` e compare o `origin` do resultado, em vez de conferir apenas o prefixo do
|
|
80
80
|
texto.
|
|
@@ -47,26 +47,26 @@ Declare o schedule com `defineSchedule` e registre-o no domínio, ao lado da act
|
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
49
|
import { createRuntime, defineDomain, defineSchedule } from '@softize/opus/core'
|
|
50
|
-
import {
|
|
50
|
+
import { ledgerClose } from './ledger-close.ts' // a action 'ledger.close', preparada abaixo
|
|
51
51
|
|
|
52
|
-
const
|
|
53
|
-
name: '
|
|
54
|
-
action: '
|
|
52
|
+
const closeDay = defineSchedule({
|
|
53
|
+
name: 'ledger.close-day',
|
|
54
|
+
action: 'ledger.close',
|
|
55
55
|
cron: '0 23 * * *',
|
|
56
56
|
timezone: 'America/Sao_Paulo',
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
export const
|
|
60
|
-
name: '
|
|
61
|
-
actions: {
|
|
62
|
-
schedules: [
|
|
59
|
+
export const ledgerDomain = defineDomain({
|
|
60
|
+
name: 'ledger',
|
|
61
|
+
actions: { ledgerClose },
|
|
62
|
+
schedules: [closeDay],
|
|
63
63
|
})
|
|
64
64
|
|
|
65
65
|
const runtime = createRuntime({
|
|
66
66
|
// …server/data…
|
|
67
67
|
scheduler,
|
|
68
68
|
})
|
|
69
|
-
runtime.register([
|
|
69
|
+
runtime.register([ledgerDomain])
|
|
70
70
|
await runtime.start()
|
|
71
71
|
```
|
|
72
72
|
|
|
@@ -91,18 +91,18 @@ recusa o sistema até que o contrato dela aceite essa execução com `automatabl
|
|
|
91
91
|
```ts
|
|
92
92
|
import { defineContract, isSystemActor } from '@softize/opus/core'
|
|
93
93
|
|
|
94
|
-
export const
|
|
95
|
-
name: '
|
|
94
|
+
export const ledgerCloseContract = defineContract({
|
|
95
|
+
name: 'ledger.close',
|
|
96
96
|
kind: 'simple',
|
|
97
97
|
input: z.object({}),
|
|
98
|
-
output: z.object({
|
|
98
|
+
output: z.object({ closedEntries: z.number() }),
|
|
99
99
|
automatable: true,
|
|
100
100
|
})
|
|
101
101
|
|
|
102
|
-
export const
|
|
102
|
+
export const ledgerClose = bindAction(ledgerCloseContract, {
|
|
103
103
|
// O sistema não tem permissões: aceite-o de forma explícita ao lado da regra das pessoas.
|
|
104
|
-
authorize: (ctx) => isSystemActor(ctx) || ctx.can('
|
|
105
|
-
handler: async (ctx) => ({
|
|
104
|
+
authorize: (ctx) => isSystemActor(ctx) || ctx.can('ledger:close'),
|
|
105
|
+
handler: async (ctx) => ({ closedEntries: await ledger.closeDay() }),
|
|
106
106
|
})
|
|
107
107
|
```
|
|
108
108
|
|
|
@@ -70,8 +70,8 @@ runtime: `ctx.user` é `null`, `ctx.can` nega tudo e `isSystemActor(ctx)` respon
|
|
|
70
70
|
|
|
71
71
|
```ts
|
|
72
72
|
it('o fechamento diário roda pelo sistema', async () => {
|
|
73
|
-
const { output } = await runAction(
|
|
74
|
-
expect(output.
|
|
73
|
+
const { output } = await runAction(ledgerClose, {}, { schedule: 'ledger.close-day' })
|
|
74
|
+
expect(output.closedEntries).toBeGreaterThan(0)
|
|
75
75
|
})
|
|
76
76
|
```
|
|
77
77
|
|
|
@@ -102,8 +102,8 @@ validação de chave dos drivers reais:
|
|
|
102
102
|
import { memStorage, runAction } from '@softize/opus/testing'
|
|
103
103
|
|
|
104
104
|
const storage = memStorage()
|
|
105
|
-
await runAction(
|
|
106
|
-
expect(storage.keys()).toEqual(['
|
|
105
|
+
await runAction(invoiceAttach, { id: '9' }, { user, storage })
|
|
106
|
+
expect(storage.keys()).toEqual(['invoices/9.pdf'])
|
|
107
107
|
```
|
|
108
108
|
|
|
109
109
|
## fake — dados gerados pelo schema
|
package/src/vite/design.ts
CHANGED
|
@@ -89,7 +89,7 @@ export interface OpusDesignOptions {
|
|
|
89
89
|
entry?: string | string[]
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
|
-
* Cenários de design (ADR 0037): módulos que exportam `defineDesignScenario(
|
|
92
|
+
* Cenários de design (ADR 0037): módulos que exportam `defineDesignScenario(contract, response)`.
|
|
93
93
|
* Aceita caminhos e globs, como `entry`. O cenário vence a resposta padrão gerada pelo `fake`;
|
|
94
94
|
* cenário de action inexistente impede o boot, com a lista no erro.
|
|
95
95
|
* Sem default: o projeto decide onde os cenários ficam e se são versionados.
|