@open-mercato/core 0.6.3-develop.3809.1.bde5459e65 → 0.6.3-develop.3811.1.be22750402
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/AGENTS.md +37 -1
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +26 -7
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +9 -4
- package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +14 -4
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/auth/AGENTS.md +27 -0
- package/src/modules/catalog/AGENTS.md +21 -2
- package/src/modules/currencies/AGENTS.md +21 -2
- package/src/modules/customer_accounts/AGENTS.md +26 -6
- package/src/modules/customers/AGENTS.md +20 -1
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +33 -11
- package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +13 -7
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +20 -6
- package/src/modules/customers/i18n/de.json +3 -5
- package/src/modules/customers/i18n/en.json +0 -2
- package/src/modules/customers/i18n/es.json +3 -5
- package/src/modules/customers/i18n/pl.json +3 -5
- package/src/modules/data_sync/AGENTS.md +30 -11
- package/src/modules/integrations/AGENTS.md +31 -13
- package/src/modules/progress/AGENTS.md +20 -2
- package/src/modules/sales/AGENTS.md +24 -5
- package/src/modules/workflows/AGENTS.md +25 -3
|
@@ -669,7 +669,7 @@
|
|
|
669
669
|
"customers.deals.create.submit": "Deal erstellen",
|
|
670
670
|
"customers.deals.create.title": "Deal erstellen",
|
|
671
671
|
"customers.deals.detail.actions.apply": "Apply",
|
|
672
|
-
"customers.deals.detail.actions.backToList": "
|
|
672
|
+
"customers.deals.detail.actions.backToList": "Zurück zu Deals",
|
|
673
673
|
"customers.deals.detail.actions.cancel": "Cancel",
|
|
674
674
|
"customers.deals.detail.actions.delete": "Delete",
|
|
675
675
|
"customers.deals.detail.actions.moveStage": "Phase ändern",
|
|
@@ -686,7 +686,6 @@
|
|
|
686
686
|
"customers.deals.detail.activitiesEmptyAction": "Aktivität hinzufügen",
|
|
687
687
|
"customers.deals.detail.activitiesEmptyTitle": "Noch keine Aktivitäten",
|
|
688
688
|
"customers.deals.detail.activitiesLoading": "Aktivitäten werden geladen…",
|
|
689
|
-
"customers.deals.detail.backToList": "Zur Deal-Liste",
|
|
690
689
|
"customers.deals.detail.badge.deal": "Deal",
|
|
691
690
|
"customers.deals.detail.badge.lost": "Lost",
|
|
692
691
|
"customers.deals.detail.badge.won": "Won",
|
|
@@ -707,8 +706,8 @@
|
|
|
707
706
|
"customers.deals.detail.deleteError": "Deal konnte nicht gelöscht werden.",
|
|
708
707
|
"customers.deals.detail.deleteSuccess": "Deal gelöscht.",
|
|
709
708
|
"customers.deals.detail.editAssignments": "Zuordnungen bearbeiten",
|
|
710
|
-
"customers.deals.detail.error.load": "
|
|
711
|
-
"customers.deals.detail.error.notFound": "Deal
|
|
709
|
+
"customers.deals.detail.error.load": "Deal konnte nicht geladen werden.",
|
|
710
|
+
"customers.deals.detail.error.notFound": "Deal nicht gefunden.",
|
|
712
711
|
"customers.deals.detail.fields.expectedClose": "Voraussichtlicher Abschluss",
|
|
713
712
|
"customers.deals.detail.fields.pipeline": "Pipeline-Stufe",
|
|
714
713
|
"customers.deals.detail.fields.probability": "Wahrscheinlichkeit",
|
|
@@ -770,7 +769,6 @@
|
|
|
770
769
|
"customers.deals.detail.noPipeline": "Keine Pipeline",
|
|
771
770
|
"customers.deals.detail.noStatus": "Kein Status",
|
|
772
771
|
"customers.deals.detail.noValue": "Keine Angaben",
|
|
773
|
-
"customers.deals.detail.notFound": "Deal wurde nicht gefunden.",
|
|
774
772
|
"customers.deals.detail.notesAdd": "Notiz hinzufügen",
|
|
775
773
|
"customers.deals.detail.notesEmpty": "Noch keine Notizen.",
|
|
776
774
|
"customers.deals.detail.notesEmptyAction": "Notiz hinzufügen",
|
|
@@ -686,7 +686,6 @@
|
|
|
686
686
|
"customers.deals.detail.activitiesEmptyAction": "Add an activity",
|
|
687
687
|
"customers.deals.detail.activitiesEmptyTitle": "No activities yet",
|
|
688
688
|
"customers.deals.detail.activitiesLoading": "Loading activities…",
|
|
689
|
-
"customers.deals.detail.backToList": "Back to deals",
|
|
690
689
|
"customers.deals.detail.badge.deal": "Deal",
|
|
691
690
|
"customers.deals.detail.badge.lost": "Lost",
|
|
692
691
|
"customers.deals.detail.badge.won": "Won",
|
|
@@ -770,7 +769,6 @@
|
|
|
770
769
|
"customers.deals.detail.noPipeline": "No pipeline",
|
|
771
770
|
"customers.deals.detail.noStatus": "No status",
|
|
772
771
|
"customers.deals.detail.noValue": "Not provided",
|
|
773
|
-
"customers.deals.detail.notFound": "Deal not found.",
|
|
774
772
|
"customers.deals.detail.notesAdd": "Add note",
|
|
775
773
|
"customers.deals.detail.notesEmpty": "No notes yet.",
|
|
776
774
|
"customers.deals.detail.notesEmptyAction": "Add a note",
|
|
@@ -669,7 +669,7 @@
|
|
|
669
669
|
"customers.deals.create.submit": "Crear oportunidad",
|
|
670
670
|
"customers.deals.create.title": "Crear oportunidad",
|
|
671
671
|
"customers.deals.detail.actions.apply": "Apply",
|
|
672
|
-
"customers.deals.detail.actions.backToList": "
|
|
672
|
+
"customers.deals.detail.actions.backToList": "Volver a los deals",
|
|
673
673
|
"customers.deals.detail.actions.cancel": "Cancel",
|
|
674
674
|
"customers.deals.detail.actions.delete": "Delete",
|
|
675
675
|
"customers.deals.detail.actions.moveStage": "Mover etapa",
|
|
@@ -686,7 +686,6 @@
|
|
|
686
686
|
"customers.deals.detail.activitiesEmptyAction": "Agregar actividad",
|
|
687
687
|
"customers.deals.detail.activitiesEmptyTitle": "Aún no hay actividades",
|
|
688
688
|
"customers.deals.detail.activitiesLoading": "Cargando actividades…",
|
|
689
|
-
"customers.deals.detail.backToList": "Volver a los deals",
|
|
690
689
|
"customers.deals.detail.badge.deal": "Deal",
|
|
691
690
|
"customers.deals.detail.badge.lost": "Lost",
|
|
692
691
|
"customers.deals.detail.badge.won": "Won",
|
|
@@ -707,8 +706,8 @@
|
|
|
707
706
|
"customers.deals.detail.deleteError": "No se pudo eliminar el deal.",
|
|
708
707
|
"customers.deals.detail.deleteSuccess": "Deal eliminado.",
|
|
709
708
|
"customers.deals.detail.editAssignments": "Editar vínculos",
|
|
710
|
-
"customers.deals.detail.error.load": "
|
|
711
|
-
"customers.deals.detail.error.notFound": "
|
|
709
|
+
"customers.deals.detail.error.load": "No se pudo cargar el deal.",
|
|
710
|
+
"customers.deals.detail.error.notFound": "No se encontró el deal.",
|
|
712
711
|
"customers.deals.detail.fields.expectedClose": "Cierre previsto",
|
|
713
712
|
"customers.deals.detail.fields.pipeline": "Etapa del pipeline",
|
|
714
713
|
"customers.deals.detail.fields.probability": "Probabilidad",
|
|
@@ -770,7 +769,6 @@
|
|
|
770
769
|
"customers.deals.detail.noPipeline": "Sin pipeline",
|
|
771
770
|
"customers.deals.detail.noStatus": "Sin estado",
|
|
772
771
|
"customers.deals.detail.noValue": "Sin datos",
|
|
773
|
-
"customers.deals.detail.notFound": "No se encontró el deal.",
|
|
774
772
|
"customers.deals.detail.notesAdd": "Agregar nota",
|
|
775
773
|
"customers.deals.detail.notesEmpty": "Aún no hay notas.",
|
|
776
774
|
"customers.deals.detail.notesEmptyAction": "Agregar nota",
|
|
@@ -669,7 +669,7 @@
|
|
|
669
669
|
"customers.deals.create.submit": "Utwórz szansę",
|
|
670
670
|
"customers.deals.create.title": "Utwórz szansę",
|
|
671
671
|
"customers.deals.detail.actions.apply": "Apply",
|
|
672
|
-
"customers.deals.detail.actions.backToList": "
|
|
672
|
+
"customers.deals.detail.actions.backToList": "Powrót do listy szans",
|
|
673
673
|
"customers.deals.detail.actions.cancel": "Cancel",
|
|
674
674
|
"customers.deals.detail.actions.delete": "Delete",
|
|
675
675
|
"customers.deals.detail.actions.moveStage": "Zmień etap",
|
|
@@ -686,7 +686,6 @@
|
|
|
686
686
|
"customers.deals.detail.activitiesEmptyAction": "Dodaj aktywność",
|
|
687
687
|
"customers.deals.detail.activitiesEmptyTitle": "Brak aktywności",
|
|
688
688
|
"customers.deals.detail.activitiesLoading": "Ładowanie aktywności…",
|
|
689
|
-
"customers.deals.detail.backToList": "Wróć do listy szans",
|
|
690
689
|
"customers.deals.detail.badge.deal": "Deal",
|
|
691
690
|
"customers.deals.detail.badge.lost": "Lost",
|
|
692
691
|
"customers.deals.detail.badge.won": "Won",
|
|
@@ -707,8 +706,8 @@
|
|
|
707
706
|
"customers.deals.detail.deleteError": "Nie udało się usunąć szansy.",
|
|
708
707
|
"customers.deals.detail.deleteSuccess": "Szansa została usunięta.",
|
|
709
708
|
"customers.deals.detail.editAssignments": "Edytuj powiązania",
|
|
710
|
-
"customers.deals.detail.error.load": "
|
|
711
|
-
"customers.deals.detail.error.notFound": "
|
|
709
|
+
"customers.deals.detail.error.load": "Nie udało się załadować szansy.",
|
|
710
|
+
"customers.deals.detail.error.notFound": "Nie znaleziono szansy.",
|
|
712
711
|
"customers.deals.detail.fields.expectedClose": "Przewidywana data zamknięcia",
|
|
713
712
|
"customers.deals.detail.fields.pipeline": "Etap",
|
|
714
713
|
"customers.deals.detail.fields.probability": "Prawdopodobieństwo",
|
|
@@ -770,7 +769,6 @@
|
|
|
770
769
|
"customers.deals.detail.noPipeline": "Brak etapu",
|
|
771
770
|
"customers.deals.detail.noStatus": "Brak statusu",
|
|
772
771
|
"customers.deals.detail.noValue": "Brak danych",
|
|
773
|
-
"customers.deals.detail.notFound": "Nie znaleziono szansy.",
|
|
774
772
|
"customers.deals.detail.notesAdd": "Dodaj notatkę",
|
|
775
773
|
"customers.deals.detail.notesEmpty": "Brak notatek.",
|
|
776
774
|
"customers.deals.detail.notesEmptyAction": "Dodaj notatkę",
|
|
@@ -6,6 +6,36 @@ The `data_sync` module provides a streaming data synchronization hub for import/
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## Always
|
|
10
|
+
|
|
11
|
+
- **Always scope by organizationId + tenantId** — every entity query
|
|
12
|
+
- **Use the queue system** — never run syncs inline in API handlers
|
|
13
|
+
- **New sync providers MUST support provider-owned env preconfiguration** when fresh installs need credentials or default mappings/locales/channels from deployment env
|
|
14
|
+
- **Persist cursor after each batch** — enables resume on failure
|
|
15
|
+
- **Log item-level errors** — don't stop the sync for individual item failures
|
|
16
|
+
- **Check for overlap** before starting a new run (same integration + entityType + direction)
|
|
17
|
+
- **API routes must export `openApi`** for documentation generation
|
|
18
|
+
|
|
19
|
+
## Ask First
|
|
20
|
+
|
|
21
|
+
- Ask before changing adapter contracts, run lifecycle states, cursor semantics, queue names, or overlap detection.
|
|
22
|
+
- Ask before adding provider-specific logic to this generic module.
|
|
23
|
+
- Ask before changing progress delivery or cancellation behavior.
|
|
24
|
+
|
|
25
|
+
## Never
|
|
26
|
+
|
|
27
|
+
- Never import from provider adapter modules — `data_sync` is generic.
|
|
28
|
+
- Never run syncs inline in API handlers.
|
|
29
|
+
- Never add frontend polling loops for sync progress beyond initial hydration or reconnect recovery.
|
|
30
|
+
- Never special-case provider credentials, mappings, or state in `data_sync`.
|
|
31
|
+
|
|
32
|
+
## Validation Commands
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
yarn generate
|
|
36
|
+
yarn workspace @open-mercato/core build
|
|
37
|
+
```
|
|
38
|
+
|
|
9
39
|
## Module Structure
|
|
10
40
|
|
|
11
41
|
```
|
|
@@ -152,14 +182,3 @@ Data sync providers can leverage the **Unified Module Extension System (UMES)**
|
|
|
152
182
|
- Use helpers from `@open-mercato/core/modules/core/__integration__/helpers/*`
|
|
153
183
|
- Tests must create prerequisites via API and clean up in `finally`
|
|
154
184
|
- Avoid hard dependency on late-phase modules; keep tests scoped to implemented contracts
|
|
155
|
-
|
|
156
|
-
## MUST Rules
|
|
157
|
-
|
|
158
|
-
- **Always scope by organizationId + tenantId** — every entity query
|
|
159
|
-
- **Never import from provider adapter modules** — data_sync is generic
|
|
160
|
-
- **Use the queue system** — never run syncs inline in API handlers
|
|
161
|
-
- **New sync providers MUST support provider-owned env preconfiguration** when fresh installs need credentials or default mappings/locales/channels from deployment env
|
|
162
|
-
- **Persist cursor after each batch** — enables resume on failure
|
|
163
|
-
- **Log item-level errors** — don't stop the sync for individual item failures
|
|
164
|
-
- **Check for overlap** before starting a new run (same integration + entityType + direction)
|
|
165
|
-
- **API routes must export `openApi`** for documentation generation
|
|
@@ -6,6 +6,37 @@ The `integrations` module is the foundation layer for all external connectors (p
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## Always
|
|
10
|
+
|
|
11
|
+
- **Always scope by organizationId + tenantId** — every entity query and service call
|
|
12
|
+
- **Use `findWithDecryption`/`findOneWithDecryption`** for credential reads
|
|
13
|
+
- **New providers MUST support provider-owned env preconfiguration** when credentials/settings are deployment-managed; implement it in the provider package, not in core
|
|
14
|
+
- **Health check services** must be registered in DI by the provider module, not by integrations
|
|
15
|
+
- **API routes must export `openApi`** for documentation generation
|
|
16
|
+
- **All user-facing strings** via i18n keys in `i18n/en.json`
|
|
17
|
+
- **Keep ACL default export shape** consistent: `export const features = [...]; export default features`
|
|
18
|
+
- **Registry/type contracts** live in `@open-mercato/shared/modules/integrations/types`
|
|
19
|
+
|
|
20
|
+
## Ask First
|
|
21
|
+
|
|
22
|
+
- Ask before changing credential resolution order, registry type contracts, canonical API routes, or compatibility surfaces.
|
|
23
|
+
- Ask before moving provider-specific logic into this module.
|
|
24
|
+
- Ask before changing health-check timeouts, log retention semantics, or credential redaction behavior.
|
|
25
|
+
|
|
26
|
+
## Never
|
|
27
|
+
|
|
28
|
+
- Never import from provider modules — integrations module is generic; providers import from integrations, not vice versa.
|
|
29
|
+
- Never log credential values — log service strips secret fields from payload.
|
|
30
|
+
- Never special-case provider env presets, credentials, mappings, or enabled state in core.
|
|
31
|
+
- Never remove legacy `integrations.detail:tabs` fallback without a compatibility plan.
|
|
32
|
+
|
|
33
|
+
## Validation Commands
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
yarn generate
|
|
37
|
+
yarn workspace @open-mercato/core build
|
|
38
|
+
```
|
|
39
|
+
|
|
9
40
|
## Module Structure
|
|
10
41
|
|
|
11
42
|
```
|
|
@@ -192,16 +223,3 @@ The integrations module itself uses UMES to inject external ID displays on any e
|
|
|
192
223
|
- Module-local integration tests go under `__integration__/`
|
|
193
224
|
- Use helpers from `@open-mercato/core/modules/core/__integration__/helpers/*`
|
|
194
225
|
- Tests must create prerequisites via API and clean up in `finally`
|
|
195
|
-
|
|
196
|
-
## MUST Rules
|
|
197
|
-
|
|
198
|
-
- **Never import from provider modules** — integrations module is generic; providers import from integrations, not vice versa
|
|
199
|
-
- **Always scope by organizationId + tenantId** — every entity query and service call
|
|
200
|
-
- **Use `findWithDecryption`/`findOneWithDecryption`** for credential reads
|
|
201
|
-
- **New providers MUST support provider-owned env preconfiguration** when credentials/settings are deployment-managed; implement it in the provider package, not in core
|
|
202
|
-
- **Never log credential values** — log service strips secret fields from payload
|
|
203
|
-
- **Health check services** must be registered in DI by the provider module, not by integrations
|
|
204
|
-
- **API routes must export `openApi`** for documentation generation
|
|
205
|
-
- **All user-facing strings** via i18n keys in `i18n/en.json`
|
|
206
|
-
- **Keep ACL default export shape** consistent: `export const features = [...]; export default features`
|
|
207
|
-
- **Registry/type contracts** live in `@open-mercato/shared/modules/integrations/types`
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Use the progress module for every user-visible bulk operation and every long-running operation. Keep `ProgressTopBar` the single shared progress surface.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
7
|
1. **MUST create `ProgressJob` for durable work** — imports, exports, bulk mutations, reindexing, external sync, and queued work must persist progress server-side.
|
|
8
8
|
2. **MUST return `progressJobId` to the UI** — DataTable bulk actions and start-operation APIs must expose the job id so the top bar can track it.
|
|
@@ -11,7 +11,25 @@ Use the progress module for every user-visible bulk operation and every long-run
|
|
|
11
11
|
5. **MUST use queue workers for durable work** — use `@open-mercato/queue`; do not implement custom queues, timers, or page polling loops.
|
|
12
12
|
6. **MUST run mutations through commands** — workers must use `commandBus.execute(...)` for domain writes so audit, undo, cache, events, and index invalidation stay intact.
|
|
13
13
|
7. **MUST use client-local progress only for browser-bound loops** — local `client:*` progress events are best-effort and must not represent work that should survive navigation.
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
## Ask First
|
|
16
|
+
|
|
17
|
+
- Ask before adding a new progress mode, changing job terminal states, or changing cancellation semantics.
|
|
18
|
+
- Ask before creating a module-specific progress UI for work that could use the shared top bar.
|
|
19
|
+
|
|
20
|
+
## Never
|
|
21
|
+
|
|
22
|
+
- Never leave running jobs without heartbeat/progress updates.
|
|
23
|
+
- Never implement custom queues, timers, or page polling loops for durable work.
|
|
24
|
+
- Never represent durable server work with client-local `client:*` progress events.
|
|
25
|
+
- Never build per-module progress bars for global operations — use `ProgressTopBar` and shared progress hooks.
|
|
26
|
+
|
|
27
|
+
## Validation Commands
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
yarn generate
|
|
31
|
+
yarn workspace @open-mercato/core build
|
|
32
|
+
```
|
|
15
33
|
|
|
16
34
|
## Choosing Progress Mode
|
|
17
35
|
|
|
@@ -2,13 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
Use the sales module for orders, quotes, invoices, shipments, and payments. This module has the most complex business logic in the system.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
|
-
1. **MUST
|
|
7
|
+
1. **MUST use `salesCalculationService` from DI** for document math.
|
|
8
8
|
2. **MUST follow document flow**: Quote → Order → Invoice — no skipping steps
|
|
9
|
-
3. **MUST
|
|
10
|
-
4. **MUST
|
|
11
|
-
|
|
9
|
+
3. **MUST use `selectBestPrice`** from catalog pricing helpers.
|
|
10
|
+
4. **MUST scope all documents to a channel** — channel selection affects pricing, numbering, and visibility
|
|
11
|
+
|
|
12
|
+
## Ask First
|
|
13
|
+
|
|
14
|
+
- Ask before changing the Quote → Order → Invoice flow, workflow states, numbering rules, or channel scoping behavior.
|
|
15
|
+
- Ask before changing configuration entity semantics for statuses, methods, channels, price kinds, adjustment kinds, or document numbers.
|
|
16
|
+
|
|
17
|
+
## Never
|
|
18
|
+
|
|
19
|
+
- Never reimplement document math inline.
|
|
20
|
+
- Never skip configured document workflow states.
|
|
21
|
+
- Never modify configuration entities directly; use the admin UI or setup hooks.
|
|
22
|
+
- Never inline price calculations.
|
|
23
|
+
|
|
24
|
+
## Validation Commands
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
yarn db:generate
|
|
28
|
+
yarn generate
|
|
29
|
+
yarn workspace @open-mercato/core build
|
|
30
|
+
```
|
|
12
31
|
|
|
13
32
|
## Document Flow
|
|
14
33
|
|
|
@@ -2,19 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
Use the workflows module for business process automation: defining step-based workflows, executing instances, handling user tasks, processing async activities, and triggering workflows from domain events.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
7
|
1. **MUST resolve services via DI** — use `container.resolve('workflowExecutor')`, never import and call lib functions directly
|
|
8
|
-
2. **MUST
|
|
8
|
+
2. **MUST use `workflowExecutor.startWorkflow()`** to create and run instances.
|
|
9
9
|
3. **MUST follow the step state machine** — steps transition `PENDING → ACTIVE → COMPLETED|FAILED|SKIPPED|CANCELLED`; never set status out of order
|
|
10
10
|
4. **MUST follow the instance state machine** — instances transition `RUNNING → COMPLETED|FAILED|CANCELLED`; intermediate states include `PAUSED`, `WAITING_FOR_ACTIVITIES`, `COMPENSATING`
|
|
11
11
|
5. **MUST keep activity handlers idempotent** — check state before mutating; activities may be retried on failure
|
|
12
12
|
6. **MUST use event sourcing** — log all workflow events via `eventLogger.logWorkflowEvent()`; never mutate instance state without a corresponding event
|
|
13
13
|
7. **MUST use variable interpolation** for dynamic activity config — use `{{context.*}}`, `{{workflow.*}}`, `{{env.*}}`, `{{now}}`; never hardcode values
|
|
14
|
-
8. **MUST
|
|
14
|
+
8. **MUST use event triggers, signals, and widget injection** for cross-module integration.
|
|
15
15
|
9. **MUST declare new events in `events.ts`** with `as const` — undeclared events trigger TypeScript errors and runtime warnings
|
|
16
16
|
10. **MUST scope all queries by `organization_id`** — workflow data is tenant-scoped; never expose cross-tenant instances or tasks
|
|
17
17
|
|
|
18
|
+
## Ask First
|
|
19
|
+
|
|
20
|
+
- Ask before changing workflow, step, or activity state machines.
|
|
21
|
+
- Ask before changing SSRF guard behavior, private URL allowances, compensation semantics, or trigger storm controls.
|
|
22
|
+
- Ask before coupling another module directly to workflow internals.
|
|
23
|
+
|
|
24
|
+
## Never
|
|
25
|
+
|
|
26
|
+
- Never import and call workflow lib functions directly instead of resolving DI services.
|
|
27
|
+
- Never skip the execution loop or insert `WorkflowInstance` rows directly.
|
|
28
|
+
- Never mutate instance state without a corresponding workflow event.
|
|
29
|
+
- Never expose cross-tenant workflow instances or tasks.
|
|
30
|
+
- Never leave `OM_WORKFLOWS_ALLOW_PRIVATE_URLS` enabled in production.
|
|
31
|
+
|
|
32
|
+
## Validation Commands
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
yarn db:generate
|
|
36
|
+
yarn generate
|
|
37
|
+
yarn workspace @open-mercato/core build
|
|
38
|
+
```
|
|
39
|
+
|
|
18
40
|
## Execution Architecture
|
|
19
41
|
|
|
20
42
|
```
|