@fayz-ai/plugin-production 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Faya Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,38 @@
1
+ import { type PluginManifest } from '@fayz-ai/core';
2
+ export { ProductionPage, type ProductionPageProps } from './views/ProductionPage';
3
+ export { ProductionOverviewView, ProductionPlanningView, ProductionOrdersView, ProductionExecutionView, ProductionBatchesView, ProductionCostsView, } from './views/GapScreens';
4
+ export interface ProductionPluginOptions {
5
+ navSection?: 'main' | 'secondary';
6
+ navPosition?: number;
7
+ navLabel?: string;
8
+ /** Como a página desenha as seis telas irmãs. `tabs` é o desenho do Estoque. */
9
+ moduleNav?: 'rail' | 'tabs' | 'sidebar';
10
+ }
11
+ /**
12
+ * Produção — as seis telas do menu do V1, todas esqueleto.
13
+ *
14
+ * ── Quem recebe ─────────────────────────────────────────────────────────────
15
+ * Quem tem o aplicativo `resto` (ChefControl), e ninguém mais. A porta é
16
+ * `app.apps.preset.modules`: o ofício OFERECE o módulo, a conta dispõe (079).
17
+ * Uma conta de clínica compila este pacote e nunca o vê, porque o preset dela
18
+ * não o oferece — e é por isso que o manifesto pode nascer `defaultEnabled`
19
+ * sem entregar produção a um consultório.
20
+ *
21
+ * ── Por que ela não é uma aba do Estoque ────────────────────────────────────
22
+ * Entrada de Notas é aba do Estoque porque no V1 o caminho é `Estoque → Notas
23
+ * Fiscais → Entrada`. Produção não: ela é rubrica própria no menu do V1, com
24
+ * seis telas dentro, e quem produz abre a Produção — não abre o Estoque para
25
+ * chegar nela. No rail ela é a segunda linha sob «Estoque», irmã de «Geral».
26
+ *
27
+ * ── Por que o estado é «anunciar», e não «construir» ────────────────────────
28
+ * Medido no V1 de produção em 30/09/2026: 4 ordens em todo o histórico,
29
+ * nenhuma concluída; 27 insumos, nenhum consumido; 0 perdas; 0 lotes. O que
30
+ * existe de verdade são as 117 fichas técnicas — e essas o Estoque já tem.
31
+ * Ver `./views/GapScreens`, onde cada número está na tela.
32
+ *
33
+ * A permissão é a do Estoque (`inventory`) de propósito: Produção não é um
34
+ * feudo de permissão novo, é o que a casa faz com o que ela guarda, e um
35
+ * `feature` que nenhum papel tem abriria seis telas em «Acesso negado».
36
+ */
37
+ export declare function createProductionPlugin(options?: ProductionPluginOptions): PluginManifest;
38
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAGjE,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAA;AACjF,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,uBAAuB,EACvB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,oBAAoB,CAAA;AAE3B,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,CAAA;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CACxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,uBAA4B,GAAG,cAAc,CAwC5F"}
package/dist/index.js ADDED
@@ -0,0 +1,188 @@
1
+ import React from 'react';
2
+ import { definePlugin } from '@fayz-ai/core';
3
+ import { ComingSoon, ModulePage } from '@fayz-ai/ui';
4
+ import { useModuleNavigation, createViewRouter } from '@fayz-ai/admin';
5
+ import { jsx } from 'react/jsx-runtime';
6
+
7
+ // src/index.ts
8
+ function ProductionOverviewView() {
9
+ return /* @__PURE__ */ jsx(
10
+ ComingSoon,
11
+ {
12
+ title: "Vis\xE3o Geral",
13
+ summary: "O painel de quem toca a produ\xE7\xE3o: o que est\xE1 planejado para hoje, o que j\xE1 foi liberado, o que est\xE1 na bancada e o que saiu pronto.",
14
+ v1Path: "Produ\xE7\xE3o \u2192 Vis\xE3o Geral",
15
+ measured: "Medido no V1 em 30/09/2026: 4 ordens de produ\xE7\xE3o em TODO o hist\xF3rico, de tr\xEAs clientes \u2014 uma delas da Artorius, ainda em rascunho. Nenhuma das quatro foi conclu\xEDda.",
16
+ missing: [
17
+ "O painel s\xF3 existe depois que houver ordem: hoje ele mostraria quatro linhas do sistema inteiro",
18
+ "Decidir o recorte \u2014 por dia e por local de produ\xE7\xE3o, como a cozinha pensa, e n\xE3o por m\xEAs",
19
+ "Antes de tudo: confirmar com a Artorius se a produ\xE7\xE3o deles passa a ser registrada aqui ou segue na planilha"
20
+ ]
21
+ }
22
+ );
23
+ }
24
+ function ProductionPlanningView() {
25
+ return /* @__PURE__ */ jsx(
26
+ ComingSoon,
27
+ {
28
+ title: "Planejamento",
29
+ summary: "Quanto produzir de cada item e em que dia, antes de virar ordem. \xC9 o plano que olha a venda prevista e o saldo em estoque e diz o que falta fazer.",
30
+ v1Path: "Produ\xE7\xE3o \u2192 Planejamento",
31
+ measured: "3 itens de plano no V1 inteiro, um deles da Artorius (31/08/2026). Dois j\xE1 viraram ordem, um ficou aberto.",
32
+ missing: [
33
+ "A grade do plano por data e produto, com a quantidade planejada e a unidade de medida",
34
+ "A ponte \xABplano \u2192 ordem\xBB: o V1 guarda `production_order_id` no item do plano, e \xE9 assim que o plano sabe o que j\xE1 saiu do papel",
35
+ "A conta que justifica a tela: previs\xE3o de venda menos saldo em estoque. Sem ela o planejamento \xE9 digita\xE7\xE3o"
36
+ ]
37
+ }
38
+ );
39
+ }
40
+ function ProductionOrdersView() {
41
+ return /* @__PURE__ */ jsx(
42
+ ComingSoon,
43
+ {
44
+ title: "Ordens de Produ\xE7\xE3o",
45
+ summary: "O documento da produ\xE7\xE3o: que ficha t\xE9cnica, quanto, para quando, em que local, e em que estado est\xE1 \u2014 rascunho, liberada, em produ\xE7\xE3o, conclu\xEDda ou cancelada.",
46
+ v1Path: "Produ\xE7\xE3o \u2192 Ordens de Produ\xE7\xE3o",
47
+ measured: "4 ordens no V1 inteiro (1 rascunho da Artorius, 1 liberada, 1 rascunho e 1 cancelada de outro cliente). Nenhuma tem data de t\xE9rmino: o ciclo nunca foi fechado em nenhum cliente.",
48
+ missing: [
49
+ "O cabe\xE7alho da ordem com a ficha t\xE9cnica CONGELADA no momento da libera\xE7\xE3o \u2014 o V1 guarda `recipe_snapshot`, e sem isso mudar a receita reescreve o passado",
50
+ "Os estados e quem pode mov\xEA-los: liberar, concluir, cancelar e estornar s\xE3o quatro autoriza\xE7\xF5es diferentes",
51
+ "As 117 fichas t\xE9cnicas do V1 (51 da Artorius, com 232 linhas de ingrediente) j\xE1 s\xE3o a mat\xE9ria-prima desta tela \u2014 esta parte n\xE3o precisa ser inventada"
52
+ ]
53
+ }
54
+ );
55
+ }
56
+ function ProductionExecutionView() {
57
+ return /* @__PURE__ */ jsx(
58
+ ComingSoon,
59
+ {
60
+ title: "Execu\xE7\xE3o",
61
+ summary: "A produ\xE7\xE3o acontecendo: as etapas da ordem, a bancada de cada uma, quem executou, quando come\xE7ou e quando terminou \u2014 e a baixa do insumo no estoque quando ela \xE9 consumida.",
62
+ v1Path: "Produ\xE7\xE3o \u2192 Execu\xE7\xE3o",
63
+ measured: "7 etapas registradas no V1 inteiro, nenhuma da Artorius e NENHUMA conclu\xEDda. Das 27 linhas de insumo, zero foram consumidas e zero geraram movimento de estoque: a produ\xE7\xE3o do V1 nunca baixou estoque.",
64
+ missing: [
65
+ "A etapa com bancada, tempo estimado e operador \u2014 as 9 bancadas do V1 s\xE3o as MESMAS do KDS (`kds_enabled`, `kds_role`, SLA), ent\xE3o isto encosta na cozinha",
66
+ "O consumo do insumo tem de virar movimento de estoque de verdade, pelo mesmo caminho que a sa\xEDda j\xE1 usa. \xC9 o buraco central: sem ele a produ\xE7\xE3o n\xE3o afeta saldo nenhum",
67
+ "Nenhuma bancada da Artorius existe no V1 \u2014 se a tela vier, o cadastro nasce do zero com eles"
68
+ ]
69
+ }
70
+ );
71
+ }
72
+ function ProductionBatchesView() {
73
+ return /* @__PURE__ */ jsx(
74
+ ComingSoon,
75
+ {
76
+ title: "Lotes & Rastreabilidade",
77
+ summary: "O lote e a validade do que saiu pronto, e o caminho de volta: deste lote para a ordem que o produziu, e dela para os insumos que entraram.",
78
+ v1Path: "Produ\xE7\xE3o \u2192 Lotes & Rastreabilidade",
79
+ v1AlsoMissing: true,
80
+ measured: "O V1 n\xE3o tem tabela de lote de produ\xE7\xE3o: o lote \xE9 um campo (`batch_number`) na sa\xEDda da ordem, e das 2 sa\xEDdas existentes NENHUMA tem lote ou validade preenchidos. Rastreabilidade de ponta a ponta n\xE3o existe l\xE1.",
81
+ missing: [
82
+ "Isto \xE9 funcionalidade NOVA, n\xE3o porte: n\xE3o h\xE1 nada no V1 para trazer al\xE9m de dois campos vazios",
83
+ "O que existe de lote no V1 \xE9 do lado da COMPRA \u2014 122 lotes vindos de importa\xE7\xE3o de DANFE. A liga\xE7\xE3o compra \u2192 produ\xE7\xE3o \u2192 venda \xE9 o que falta",
84
+ "Antes de construir: saber se a vigil\xE2ncia sanit\xE1ria cobra isto da Artorius. \xC9 o \xFAnico motivo que justifica a tela"
85
+ ]
86
+ }
87
+ );
88
+ }
89
+ function ProductionCostsView() {
90
+ return /* @__PURE__ */ jsx(
91
+ ComingSoon,
92
+ {
93
+ title: "Custos & Rendimentos",
94
+ summary: "Quanto custou produzir e quanto rendeu de verdade: o custo dos insumos consumidos contra o que saiu pronto, e a perda entre um e outro.",
95
+ v1Path: "Produ\xE7\xE3o \u2192 Custos & Rendimentos",
96
+ v1AlsoMissing: true,
97
+ measured: "ZERO perdas registradas no V1, em todos os clientes. E zero co-produtos (`recipe_outputs`): toda ficha t\xE9cnica de l\xE1 rende UM item s\xF3, ent\xE3o n\xE3o h\xE1 rateio de custo para calcular.",
98
+ missing: [
99
+ "A conta depende da Execu\xE7\xE3o: sem insumo consumido e sem custo unit\xE1rio no movimento, n\xE3o h\xE1 custo real para comparar com o planejado",
100
+ "O rendimento esperado J\xC1 existe na ficha t\xE9cnica (`yield_quantity`, preenchido em 117 receitas). Falta o rendimento REAL, que s\xF3 a ordem conclu\xEDda d\xE1",
101
+ "A perda \xE9 o terceiro lado: o V1 tem a tabela com motivo e custo e nunca gravou uma linha. Se vier, vem com motivo obrigat\xF3rio ou vira lixo"
102
+ ]
103
+ }
104
+ );
105
+ }
106
+ var SCREENS = [
107
+ { id: "production", view: "production", label: "Vis\xE3o Geral", icon: "LayoutDashboard", render: () => /* @__PURE__ */ jsx(ProductionOverviewView, {}) },
108
+ { id: "production-planning", view: "planning", label: "Planejamento", icon: "CalendarRange", render: () => /* @__PURE__ */ jsx(ProductionPlanningView, {}) },
109
+ { id: "production-orders", view: "orders", label: "Ordens de Produ\xE7\xE3o", icon: "ClipboardList", render: () => /* @__PURE__ */ jsx(ProductionOrdersView, {}) },
110
+ { id: "production-execution", view: "execution", label: "Execu\xE7\xE3o", icon: "Flame", render: () => /* @__PURE__ */ jsx(ProductionExecutionView, {}) },
111
+ { id: "production-batches", view: "batches", label: "Lotes & Rastreabilidade", icon: "ScanLine", render: () => /* @__PURE__ */ jsx(ProductionBatchesView, {}) },
112
+ { id: "production-costs", view: "costs", label: "Custos & Rendimentos", icon: "Calculator", render: () => /* @__PURE__ */ jsx(ProductionCostsView, {}) }
113
+ ];
114
+ function ProductionPage({
115
+ title = "Produ\xE7\xE3o",
116
+ subtitle = "Da ficha t\xE9cnica ao pronto: plano, ordem, execu\xE7\xE3o, lote e custo.",
117
+ // SEM padrão próprio: quem decide onde mora a navegação de um módulo é a
118
+ // moldura da conta (`shell.moduleNav`), como em CRM, Estoque e Financeiro.
119
+ // Fixo em 'tabs', este era o único módulo que ignorava a troca.
120
+ navVariant
121
+ }) {
122
+ const { view, direction, navigate } = useModuleNavigation("/production", {}, "production");
123
+ const nav = SCREENS.map((screen) => ({
124
+ id: screen.id,
125
+ label: screen.label,
126
+ icon: screen.icon,
127
+ active: view === screen.view,
128
+ onClick: () => navigate(screen.view)
129
+ }));
130
+ const renderView = createViewRouter(
131
+ SCREENS.map((screen) => ({ id: screen.view, render: screen.render })),
132
+ "production"
133
+ );
134
+ return /* @__PURE__ */ jsx(
135
+ ModulePage,
136
+ {
137
+ navVariant,
138
+ title,
139
+ subtitle,
140
+ nav,
141
+ showHeader: view === "production",
142
+ viewKey: view,
143
+ direction,
144
+ children: renderView(view)
145
+ }
146
+ );
147
+ }
148
+
149
+ // src/index.ts
150
+ function createProductionPlugin(options = {}) {
151
+ const PageComponent = () => React.createElement(ProductionPage, { navVariant: options.moduleNav });
152
+ return definePlugin({
153
+ id: "production",
154
+ name: options.navLabel ?? "Produ\xE7\xE3o",
155
+ icon: "Factory",
156
+ version: "0.1.0",
157
+ scope: "vertical",
158
+ defaultEnabled: true,
159
+ defaultAgentRole: "operations",
160
+ description: "Do plano \xE0 ordem, da ordem ao pronto: planejamento, execu\xE7\xE3o, lote e rendimento.",
161
+ dependencies: ["inventory"],
162
+ navigation: [
163
+ {
164
+ section: options.navSection ?? "main",
165
+ // Logo depois do Estoque (113 no aplicativo central), para a rubrica do
166
+ // preset recolher os dois na ordem em que se leem.
167
+ position: options.navPosition ?? 114,
168
+ label: options.navLabel ?? "Produ\xE7\xE3o",
169
+ route: "/production",
170
+ icon: "Factory",
171
+ permission: { feature: "inventory", action: "read" }
172
+ }
173
+ ],
174
+ routes: [
175
+ {
176
+ // `/*` e não `/production` seco: as cinco telas irmãs moram em
177
+ // `#/production/planning` e abaixo, e o casamento exato não as alcança.
178
+ path: "/production/*",
179
+ component: PageComponent,
180
+ permission: { feature: "inventory", action: "read" }
181
+ }
182
+ ]
183
+ });
184
+ }
185
+
186
+ export { ProductionBatchesView, ProductionCostsView, ProductionExecutionView, ProductionOrdersView, ProductionOverviewView, ProductionPage, ProductionPlanningView, createProductionPlugin };
187
+ //# sourceMappingURL=index.js.map
188
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/views/GapScreens.tsx","../src/views/ProductionPage.tsx","../src/index.ts"],"names":["jsx"],"mappings":";;;;;;;AAoBO,SAAS,sBAAA,GAAyB;AACvC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,gBAAA;AAAA,MACN,OAAA,EAAQ,oJAAA;AAAA,MACR,MAAA,EAAO,sCAAA;AAAA,MACP,QAAA,EAAS,0LAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,oGAAA;AAAA,QACA,2GAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;AAGO,SAAS,sBAAA,GAAyB;AACvC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,cAAA;AAAA,MACN,OAAA,EAAQ,uJAAA;AAAA,MACR,MAAA,EAAO,oCAAA;AAAA,MACP,QAAA,EAAS,+GAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,uFAAA;AAAA,QACA,iJAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;AAGO,SAAS,oBAAA,GAAuB;AACrC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,0BAAA;AAAA,MACN,OAAA,EAAQ,0LAAA;AAAA,MACR,MAAA,EAAO,gDAAA;AAAA,MACP,QAAA,EAAS,sLAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,6KAAA;AAAA,QACA,wHAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;AAGO,SAAS,uBAAA,GAA0B;AACxC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,gBAAA;AAAA,MACN,OAAA,EAAQ,8LAAA;AAAA,MACR,MAAA,EAAO,sCAAA;AAAA,MACP,QAAA,EAAS,kNAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,sKAAA;AAAA,QACA,0LAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;AAGO,SAAS,qBAAA,GAAwB;AACtC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,yBAAA;AAAA,MACN,OAAA,EAAQ,4IAAA;AAAA,MACR,MAAA,EAAO,+CAAA;AAAA,MACP,aAAA,EAAa,IAAA;AAAA,MACb,QAAA,EAAS,4OAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,gHAAA;AAAA,QACA,oLAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;AAGO,SAAS,mBAAA,GAAsB;AACpC,EAAA,uBACE,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAM,sBAAA;AAAA,MACN,OAAA,EAAQ,yIAAA;AAAA,MACR,MAAA,EAAO,4CAAA;AAAA,MACP,aAAA,EAAa,IAAA;AAAA,MACb,QAAA,EAAS,sMAAA;AAAA,MACT,OAAA,EAAS;AAAA,QACP,qJAAA;AAAA,QACA,sKAAA;AAAA,QACA;AAAA;AACF;AAAA,GACF;AAEJ;ACpGA,IAAM,OAAA,GAAU;AAAA,EACd,EAAE,EAAA,EAAI,YAAA,EAAc,IAAA,EAAM,cAAc,KAAA,EAAO,gBAAA,EAAe,IAAA,EAAM,iBAAA,EAAmB,MAAA,EAAQ,sBAAMA,GAAAA,CAAC,0BAAuB,CAAA,EAAG;AAAA,EAChI,EAAE,EAAA,EAAI,qBAAA,EAAuB,IAAA,EAAM,YAAY,KAAA,EAAO,cAAA,EAAgB,IAAA,EAAM,eAAA,EAAiB,MAAA,EAAQ,sBAAMA,GAAAA,CAAC,0BAAuB,CAAA,EAAG;AAAA,EACtI,EAAE,EAAA,EAAI,mBAAA,EAAqB,IAAA,EAAM,UAAU,KAAA,EAAO,0BAAA,EAAsB,IAAA,EAAM,eAAA,EAAiB,MAAA,EAAQ,sBAAMA,GAAAA,CAAC,wBAAqB,CAAA,EAAG;AAAA,EACtI,EAAE,EAAA,EAAI,sBAAA,EAAwB,IAAA,EAAM,aAAa,KAAA,EAAO,gBAAA,EAAY,IAAA,EAAM,OAAA,EAAS,MAAA,EAAQ,sBAAMA,GAAAA,CAAC,2BAAwB,CAAA,EAAG;AAAA,EAC7H,EAAE,EAAA,EAAI,oBAAA,EAAsB,IAAA,EAAM,WAAW,KAAA,EAAO,yBAAA,EAA2B,IAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,sBAAMA,GAAAA,CAAC,yBAAsB,CAAA,EAAG;AAAA,EACzI,EAAE,EAAA,EAAI,kBAAA,EAAoB,IAAA,EAAM,SAAS,KAAA,EAAO,sBAAA,EAAwB,IAAA,EAAM,YAAA,EAAc,MAAA,EAAQ,sBAAMA,GAAAA,CAAC,uBAAoB,CAAA;AACjI,CAAA;AAQO,SAAS,cAAA,CAAe;AAAA,EAC7B,KAAA,GAAQ,gBAAA;AAAA,EACR,QAAA,GAAW,4EAAA;AAAA;AAAA;AAAA;AAAA,EAIX;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,EAAE,MAAM,SAAA,EAAW,QAAA,KAAa,mBAAA,CAAoB,aAAA,EAAe,EAAC,EAAG,YAAY,CAAA;AAEzF,EAAA,MAAM,GAAA,GAAuB,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,MAAY;AAAA,IACpD,IAAI,MAAA,CAAO,EAAA;AAAA,IACX,OAAO,MAAA,CAAO,KAAA;AAAA,IACd,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,MAAA,EAAQ,SAAS,MAAA,CAAO,IAAA;AAAA,IACxB,OAAA,EAAS,MAAM,QAAA,CAAS,MAAA,CAAO,IAAI;AAAA,GACrC,CAAE,CAAA;AAEF,EAAA,MAAM,UAAA,GAAa,gBAAA;AAAA,IACjB,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,MAAY,EAAE,EAAA,EAAI,MAAA,CAAO,IAAA,EAAM,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAO,CAAE,CAAA;AAAA,IACpE;AAAA,GACF;AAEA,EAAA,uBACEA,GAAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACC,UAAA;AAAA,MACA,KAAA;AAAA,MACA,QAAA;AAAA,MACA,GAAA;AAAA,MACA,YAAY,IAAA,KAAS,YAAA;AAAA,MACrB,OAAA,EAAS,IAAA;AAAA,MACT,SAAA;AAAA,MAEC,qBAAW,IAAI;AAAA;AAAA,GAClB;AAEJ;;;ACxBO,SAAS,sBAAA,CAAuB,OAAA,GAAmC,EAAC,EAAmB;AAK5F,EAAA,MAAM,aAAA,GAA+B,MACnC,KAAA,CAAM,aAAA,CAAc,gBAAgB,EAAE,UAAA,EAAY,OAAA,CAAQ,SAAA,EAAW,CAAA;AAEvE,EAAA,OAAO,YAAA,CAAa;AAAA,IAClB,EAAA,EAAI,YAAA;AAAA,IACJ,IAAA,EAAM,QAAQ,QAAA,IAAY,gBAAA;AAAA,IAC1B,IAAA,EAAM,SAAA;AAAA,IACN,OAAA,EAAS,OAAA;AAAA,IACT,KAAA,EAAO,UAAA;AAAA,IACP,cAAA,EAAgB,IAAA;AAAA,IAChB,gBAAA,EAAkB,YAAA;AAAA,IAClB,WAAA,EAAa,2FAAA;AAAA,IACb,YAAA,EAAc,CAAC,WAAW,CAAA;AAAA,IAC1B,UAAA,EAAY;AAAA,MACV;AAAA,QACE,OAAA,EAAS,QAAQ,UAAA,IAAc,MAAA;AAAA;AAAA;AAAA,QAG/B,QAAA,EAAU,QAAQ,WAAA,IAAe,GAAA;AAAA,QACjC,KAAA,EAAO,QAAQ,QAAA,IAAY,gBAAA;AAAA,QAC3B,KAAA,EAAO,aAAA;AAAA,QACP,IAAA,EAAM,SAAA;AAAA,QACN,UAAA,EAAY,EAAE,OAAA,EAAS,WAAA,EAAa,QAAQ,MAAA;AAAgB;AAC9D,KACF;AAAA,IACA,MAAA,EAAQ;AAAA,MACN;AAAA;AAAA;AAAA,QAGE,IAAA,EAAM,eAAA;AAAA,QACN,SAAA,EAAW,aAAA;AAAA,QACX,UAAA,EAAY,EAAE,OAAA,EAAS,WAAA,EAAa,QAAQ,MAAA;AAAgB;AAC9D;AACF,GACD,CAAA;AACH","file":"index.js","sourcesContent":["// ---------------------------------------------------------------------------\n// As seis telas da Produção — todas esqueleto, todas MEDIDAS.\n// ---------------------------------------------------------------------------\n// Os nomes são os do menu do V1 (captura de 30/09/2026). Os números são do\n// banco de produção do V1, lidos no mesmo dia: quantas linhas existem em todos\n// os clientes, e quantas são da Artorius (tenant 12).\n//\n// O que a medição disse, e por que ela está NA TELA: a Produção do V1 é uma\n// casca. Existem 117 fichas técnicas (51 da Artorius) e 829 linhas de\n// ingrediente — isso é real e é usado. Da ficha para a frente não há nada:\n// 4 ordens em três anos, nenhuma concluída, nenhum insumo consumido, nenhum\n// lote, nenhuma perda. Portar tela por tela seria copiar um vazio.\n//\n// Por isso cada `ComingSoon` abaixo diz o tamanho do buraco antes de prometer\n// a tela: quem for priorizar isto precisa ver que o V1 também não faz.\n// ---------------------------------------------------------------------------\nimport React from 'react'\nimport { ComingSoon } from '@fayz-ai/ui'\n\n/** O painel do dia: o que está em produção agora. */\nexport function ProductionOverviewView() {\n return (\n <ComingSoon\n title=\"Visão Geral\"\n summary=\"O painel de quem toca a produção: o que está planejado para hoje, o que já foi liberado, o que está na bancada e o que saiu pronto.\"\n v1Path=\"Produção → Visão Geral\"\n measured=\"Medido no V1 em 30/09/2026: 4 ordens de produção em TODO o histórico, de três clientes — uma delas da Artorius, ainda em rascunho. Nenhuma das quatro foi concluída.\"\n missing={[\n 'O painel só existe depois que houver ordem: hoje ele mostraria quatro linhas do sistema inteiro',\n 'Decidir o recorte — por dia e por local de produção, como a cozinha pensa, e não por mês',\n 'Antes de tudo: confirmar com a Artorius se a produção deles passa a ser registrada aqui ou segue na planilha',\n ]}\n />\n )\n}\n\n/** O plano do dia/semana: quanto produzir de cada item. */\nexport function ProductionPlanningView() {\n return (\n <ComingSoon\n title=\"Planejamento\"\n summary=\"Quanto produzir de cada item e em que dia, antes de virar ordem. É o plano que olha a venda prevista e o saldo em estoque e diz o que falta fazer.\"\n v1Path=\"Produção → Planejamento\"\n measured=\"3 itens de plano no V1 inteiro, um deles da Artorius (31/08/2026). Dois já viraram ordem, um ficou aberto.\"\n missing={[\n 'A grade do plano por data e produto, com a quantidade planejada e a unidade de medida',\n 'A ponte «plano → ordem»: o V1 guarda `production_order_id` no item do plano, e é assim que o plano sabe o que já saiu do papel',\n 'A conta que justifica a tela: previsão de venda menos saldo em estoque. Sem ela o planejamento é digitação',\n ]}\n />\n )\n}\n\n/** A ordem de produção — o documento. */\nexport function ProductionOrdersView() {\n return (\n <ComingSoon\n title=\"Ordens de Produção\"\n summary=\"O documento da produção: que ficha técnica, quanto, para quando, em que local, e em que estado está — rascunho, liberada, em produção, concluída ou cancelada.\"\n v1Path=\"Produção → Ordens de Produção\"\n measured=\"4 ordens no V1 inteiro (1 rascunho da Artorius, 1 liberada, 1 rascunho e 1 cancelada de outro cliente). Nenhuma tem data de término: o ciclo nunca foi fechado em nenhum cliente.\"\n missing={[\n 'O cabeçalho da ordem com a ficha técnica CONGELADA no momento da liberação — o V1 guarda `recipe_snapshot`, e sem isso mudar a receita reescreve o passado',\n 'Os estados e quem pode movê-los: liberar, concluir, cancelar e estornar são quatro autorizações diferentes',\n 'As 117 fichas técnicas do V1 (51 da Artorius, com 232 linhas de ingrediente) já são a matéria-prima desta tela — esta parte não precisa ser inventada',\n ]}\n />\n )\n}\n\n/** O chão de fábrica: etapas, bancadas, quem fez. */\nexport function ProductionExecutionView() {\n return (\n <ComingSoon\n title=\"Execução\"\n summary=\"A produção acontecendo: as etapas da ordem, a bancada de cada uma, quem executou, quando começou e quando terminou — e a baixa do insumo no estoque quando ela é consumida.\"\n v1Path=\"Produção → Execução\"\n measured=\"7 etapas registradas no V1 inteiro, nenhuma da Artorius e NENHUMA concluída. Das 27 linhas de insumo, zero foram consumidas e zero geraram movimento de estoque: a produção do V1 nunca baixou estoque.\"\n missing={[\n 'A etapa com bancada, tempo estimado e operador — as 9 bancadas do V1 são as MESMAS do KDS (`kds_enabled`, `kds_role`, SLA), então isto encosta na cozinha',\n 'O consumo do insumo tem de virar movimento de estoque de verdade, pelo mesmo caminho que a saída já usa. É o buraco central: sem ele a produção não afeta saldo nenhum',\n 'Nenhuma bancada da Artorius existe no V1 — se a tela vier, o cadastro nasce do zero com eles',\n ]}\n />\n )\n}\n\n/** Lote e validade do que saiu pronto. */\nexport function ProductionBatchesView() {\n return (\n <ComingSoon\n title=\"Lotes & Rastreabilidade\"\n summary=\"O lote e a validade do que saiu pronto, e o caminho de volta: deste lote para a ordem que o produziu, e dela para os insumos que entraram.\"\n v1Path=\"Produção → Lotes & Rastreabilidade\"\n v1AlsoMissing\n measured=\"O V1 não tem tabela de lote de produção: o lote é um campo (`batch_number`) na saída da ordem, e das 2 saídas existentes NENHUMA tem lote ou validade preenchidos. Rastreabilidade de ponta a ponta não existe lá.\"\n missing={[\n 'Isto é funcionalidade NOVA, não porte: não há nada no V1 para trazer além de dois campos vazios',\n 'O que existe de lote no V1 é do lado da COMPRA — 122 lotes vindos de importação de DANFE. A ligação compra → produção → venda é o que falta',\n 'Antes de construir: saber se a vigilância sanitária cobra isto da Artorius. É o único motivo que justifica a tela',\n ]}\n />\n )\n}\n\n/** Quanto custou e quanto rendeu. */\nexport function ProductionCostsView() {\n return (\n <ComingSoon\n title=\"Custos & Rendimentos\"\n summary=\"Quanto custou produzir e quanto rendeu de verdade: o custo dos insumos consumidos contra o que saiu pronto, e a perda entre um e outro.\"\n v1Path=\"Produção → Custos & Rendimentos\"\n v1AlsoMissing\n measured=\"ZERO perdas registradas no V1, em todos os clientes. E zero co-produtos (`recipe_outputs`): toda ficha técnica de lá rende UM item só, então não há rateio de custo para calcular.\"\n missing={[\n 'A conta depende da Execução: sem insumo consumido e sem custo unitário no movimento, não há custo real para comparar com o planejado',\n 'O rendimento esperado JÁ existe na ficha técnica (`yield_quantity`, preenchido em 117 receitas). Falta o rendimento REAL, que só a ordem concluída dá',\n 'A perda é o terceiro lado: o V1 tem a tabela com motivo e custo e nunca gravou uma linha. Se vier, vem com motivo obrigatório ou vira lixo',\n ]}\n />\n )\n}\n","import React from 'react'\nimport { ModulePage, type ModuleNavItem } from '@fayz-ai/ui'\nimport { useModuleNavigation, createViewRouter } from '@fayz-ai/admin'\nimport {\n ProductionOverviewView,\n ProductionPlanningView,\n ProductionOrdersView,\n ProductionExecutionView,\n ProductionBatchesView,\n ProductionCostsView,\n} from './GapScreens'\n\n/**\n * O identificador da tela é o do menu do V1 (`production-planning`); a URL é\n * curta (`#/production/planning`).\n *\n * São duas coisas diferentes de propósito: o id é a chave estável com que o\n * rail, o `tenant_nav` e o agente falam da tela, e a URL é o que a pessoa lê.\n * Casar os dois daria `#/production/production/planning`, porque\n * `useModuleNavigation` traduz traço em barra.\n */\nconst SCREENS = [\n { id: 'production', view: 'production', label: 'Visão Geral', icon: 'LayoutDashboard', render: () => <ProductionOverviewView /> },\n { id: 'production-planning', view: 'planning', label: 'Planejamento', icon: 'CalendarRange', render: () => <ProductionPlanningView /> },\n { id: 'production-orders', view: 'orders', label: 'Ordens de Produção', icon: 'ClipboardList', render: () => <ProductionOrdersView /> },\n { id: 'production-execution', view: 'execution', label: 'Execução', icon: 'Flame', render: () => <ProductionExecutionView /> },\n { id: 'production-batches', view: 'batches', label: 'Lotes & Rastreabilidade', icon: 'ScanLine', render: () => <ProductionBatchesView /> },\n { id: 'production-costs', view: 'costs', label: 'Custos & Rendimentos', icon: 'Calculator', render: () => <ProductionCostsView /> },\n] as const\n\nexport interface ProductionPageProps {\n title?: string\n subtitle?: string\n navVariant?: 'rail' | 'tabs' | 'sidebar'\n}\n\nexport function ProductionPage({\n title = 'Produção',\n subtitle = 'Da ficha técnica ao pronto: plano, ordem, execução, lote e custo.',\n // SEM padrão próprio: quem decide onde mora a navegação de um módulo é a\n // moldura da conta (`shell.moduleNav`), como em CRM, Estoque e Financeiro.\n // Fixo em 'tabs', este era o único módulo que ignorava a troca.\n navVariant,\n}: ProductionPageProps) {\n const { view, direction, navigate } = useModuleNavigation('/production', {}, 'production')\n\n const nav: ModuleNavItem[] = SCREENS.map((screen) => ({\n id: screen.id,\n label: screen.label,\n icon: screen.icon,\n active: view === screen.view,\n onClick: () => navigate(screen.view),\n }))\n\n const renderView = createViewRouter(\n SCREENS.map((screen) => ({ id: screen.view, render: screen.render })),\n 'production',\n )\n\n return (\n <ModulePage\n navVariant={navVariant}\n title={title}\n subtitle={subtitle}\n nav={nav}\n showHeader={view === 'production'}\n viewKey={view}\n direction={direction}\n >\n {renderView(view)}\n </ModulePage>\n )\n}\n","import React from 'react'\nimport { definePlugin, type PluginManifest } from '@fayz-ai/core'\nimport { ProductionPage, type ProductionPageProps } from './views/ProductionPage'\n\nexport { ProductionPage, type ProductionPageProps } from './views/ProductionPage'\nexport {\n ProductionOverviewView,\n ProductionPlanningView,\n ProductionOrdersView,\n ProductionExecutionView,\n ProductionBatchesView,\n ProductionCostsView,\n} from './views/GapScreens'\n\nexport interface ProductionPluginOptions {\n navSection?: 'main' | 'secondary'\n navPosition?: number\n navLabel?: string\n /** Como a página desenha as seis telas irmãs. `tabs` é o desenho do Estoque. */\n moduleNav?: 'rail' | 'tabs' | 'sidebar'\n}\n\n/**\n * Produção — as seis telas do menu do V1, todas esqueleto.\n *\n * ── Quem recebe ─────────────────────────────────────────────────────────────\n * Quem tem o aplicativo `resto` (ChefControl), e ninguém mais. A porta é\n * `app.apps.preset.modules`: o ofício OFERECE o módulo, a conta dispõe (079).\n * Uma conta de clínica compila este pacote e nunca o vê, porque o preset dela\n * não o oferece — e é por isso que o manifesto pode nascer `defaultEnabled`\n * sem entregar produção a um consultório.\n *\n * ── Por que ela não é uma aba do Estoque ────────────────────────────────────\n * Entrada de Notas é aba do Estoque porque no V1 o caminho é `Estoque → Notas\n * Fiscais → Entrada`. Produção não: ela é rubrica própria no menu do V1, com\n * seis telas dentro, e quem produz abre a Produção — não abre o Estoque para\n * chegar nela. No rail ela é a segunda linha sob «Estoque», irmã de «Geral».\n *\n * ── Por que o estado é «anunciar», e não «construir» ────────────────────────\n * Medido no V1 de produção em 30/09/2026: 4 ordens em todo o histórico,\n * nenhuma concluída; 27 insumos, nenhum consumido; 0 perdas; 0 lotes. O que\n * existe de verdade são as 117 fichas técnicas — e essas o Estoque já tem.\n * Ver `./views/GapScreens`, onde cada número está na tela.\n *\n * A permissão é a do Estoque (`inventory`) de propósito: Produção não é um\n * feudo de permissão novo, é o que a casa faz com o que ela guarda, e um\n * `feature` que nenhum papel tem abriria seis telas em «Acesso negado».\n */\nexport function createProductionPlugin(options: ProductionPluginOptions = {}): PluginManifest {\n // SEM padrão de navegação próprio: onde mora o menu de um módulo é decisão\n // da moldura da conta (`shell.moduleNav`), como em CRM, Estoque e Financeiro.\n // Com `?? 'tabs'` aqui, Produção era o único módulo que ficava em abas depois\n // de o ofício inteiro passar para a coluna.\n const PageComponent: React.FC<any> = () =>\n React.createElement(ProductionPage, { navVariant: options.moduleNav })\n\n return definePlugin({\n id: 'production',\n name: options.navLabel ?? 'Produção',\n icon: 'Factory',\n version: '0.1.0',\n scope: 'vertical',\n defaultEnabled: true,\n defaultAgentRole: 'operations',\n description: 'Do plano à ordem, da ordem ao pronto: planejamento, execução, lote e rendimento.',\n dependencies: ['inventory'],\n navigation: [\n {\n section: options.navSection ?? 'main',\n // Logo depois do Estoque (113 no aplicativo central), para a rubrica do\n // preset recolher os dois na ordem em que se leem.\n position: options.navPosition ?? 114,\n label: options.navLabel ?? 'Produção',\n route: '/production',\n icon: 'Factory',\n permission: { feature: 'inventory', action: 'read' as const },\n },\n ],\n routes: [\n {\n // `/*` e não `/production` seco: as cinco telas irmãs moram em\n // `#/production/planning` e abaixo, e o casamento exato não as alcança.\n path: '/production/*',\n component: PageComponent,\n permission: { feature: 'inventory', action: 'read' as const },\n },\n ],\n })\n}\n"]}
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ /** O painel do dia: o que está em produção agora. */
3
+ export declare function ProductionOverviewView(): React.JSX.Element;
4
+ /** O plano do dia/semana: quanto produzir de cada item. */
5
+ export declare function ProductionPlanningView(): React.JSX.Element;
6
+ /** A ordem de produção — o documento. */
7
+ export declare function ProductionOrdersView(): React.JSX.Element;
8
+ /** O chão de fábrica: etapas, bancadas, quem fez. */
9
+ export declare function ProductionExecutionView(): React.JSX.Element;
10
+ /** Lote e validade do que saiu pronto. */
11
+ export declare function ProductionBatchesView(): React.JSX.Element;
12
+ /** Quanto custou e quanto rendeu. */
13
+ export declare function ProductionCostsView(): React.JSX.Element;
14
+ //# sourceMappingURL=GapScreens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GapScreens.d.ts","sourceRoot":"","sources":["../../src/views/GapScreens.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,qDAAqD;AACrD,wBAAgB,sBAAsB,sBAcrC;AAED,2DAA2D;AAC3D,wBAAgB,sBAAsB,sBAcrC;AAED,yCAAyC;AACzC,wBAAgB,oBAAoB,sBAcnC;AAED,qDAAqD;AACrD,wBAAgB,uBAAuB,sBActC;AAED,0CAA0C;AAC1C,wBAAgB,qBAAqB,sBAepC;AAED,qCAAqC;AACrC,wBAAgB,mBAAmB,sBAelC"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export interface ProductionPageProps {
3
+ title?: string;
4
+ subtitle?: string;
5
+ navVariant?: 'rail' | 'tabs' | 'sidebar';
6
+ }
7
+ export declare function ProductionPage({ title, subtitle, navVariant, }: ProductionPageProps): React.JSX.Element;
8
+ //# sourceMappingURL=ProductionPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProductionPage.d.ts","sourceRoot":"","sources":["../../src/views/ProductionPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AA8BzB,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CACzC;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAkB,EAClB,QAA8E,EAI9E,UAAU,GACX,EAAE,mBAAmB,qBA6BrB"}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@fayz-ai/plugin-production",
3
+ "fayz": {
4
+ "status": "preview",
5
+ "dependencies": [
6
+ "inventory"
7
+ ]
8
+ },
9
+ "version": "0.1.0",
10
+ "description": "[preview] Production: planning, orders, execution, batches and yields for a house that manufactures what it sells",
11
+ "type": "module",
12
+ "sideEffects": false,
13
+ "main": "./dist/index.js",
14
+ "module": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "peerDependencies": {
26
+ "react": "^18.0.0 || ^19.0.0",
27
+ "react-dom": "^18.0.0 || ^19.0.0",
28
+ "lucide-react": ">=0.400.0 <1.0.0"
29
+ },
30
+ "dependencies": {
31
+ "@fayz-ai/admin": "^0.33.0",
32
+ "@fayz-ai/core": "^0.33.0",
33
+ "@fayz-ai/ui": "^0.33.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/react": "^18.3.0",
37
+ "@types/react-dom": "^18.3.0",
38
+ "lucide-react": "^0.400.0",
39
+ "react": "^18.3.0",
40
+ "react-dom": "^18.3.0",
41
+ "tsup": "^8.2.0",
42
+ "typescript": "^5.5.0",
43
+ "vitest": "^4.1.5"
44
+ },
45
+ "license": "MIT",
46
+ "keywords": [
47
+ "fayz",
48
+ "fayz-plugin",
49
+ "fayz-sdk",
50
+ "production"
51
+ ],
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "scripts": {
56
+ "build": "tsup && tsc -b --force",
57
+ "dev": "tsup --watch",
58
+ "typecheck": "tsc -b tsconfig.test.json",
59
+ "clean": "rm -rf dist .tsbuildinfo",
60
+ "test": "vitest run"
61
+ }
62
+ }