@open-mercato/core 0.6.3-develop.3810.1.ad92c339f5 → 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/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/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
package/AGENTS.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
`@open-mercato/core` contains all core business modules (auth, catalog, customers, sales, etc.). This guide covers the full extensibility contract and module development patterns.
|
|
4
4
|
|
|
5
|
+
## Always
|
|
6
|
+
|
|
7
|
+
- Preserve auto-discovery contracts for module files, API routes, pages, subscribers, workers, widgets, and generated registries.
|
|
8
|
+
- Export `openApi` from every API route file.
|
|
9
|
+
- Use `makeCrudRoute` with `indexer: { entityType }` for CRUD routes that should participate in query indexing.
|
|
10
|
+
- Wire custom write routes through the mutation guard contract.
|
|
11
|
+
- Use declarative feature guards and add new `acl.ts` features to `setup.ts` `defaultRoleFeatures`.
|
|
12
|
+
- Use `findWithDecryption` / `findOneWithDecryption` for encrypted entities.
|
|
13
|
+
- Implement domain writes through commands so audit, undo, cache, events, and indexing stay consistent.
|
|
14
|
+
- Run `yarn generate` after changing module files discovered by the generator.
|
|
15
|
+
|
|
16
|
+
## Ask First
|
|
17
|
+
|
|
18
|
+
- Ask before changing any contract surface from `BACKWARD_COMPATIBILITY.md`: auto-discovery, public types, import paths, event IDs, widget spot IDs, API URLs, DB schema, DI names, ACL features, notification IDs, CLI commands, or generated file contracts.
|
|
19
|
+
- Ask before moving versioned generated files or changing where generated registries live.
|
|
20
|
+
- Ask before applying migrations with `yarn db:migrate`; normal PRs should include migration files and snapshots.
|
|
21
|
+
|
|
22
|
+
## Never
|
|
23
|
+
|
|
24
|
+
- Never create direct ORM relationships between modules; use foreign key IDs and fetch separately.
|
|
25
|
+
- Never expose cross-tenant data or omit tenant/organization scoping.
|
|
26
|
+
- Never hand-edit generated files.
|
|
27
|
+
- Never import generated app bootstrap files from packages.
|
|
28
|
+
- Never run raw `em.find` / `em.findOne` between scalar mutations and `em.flush()` on the same `EntityManager` without `withAtomicFlush`.
|
|
29
|
+
- Never hand-roll AES/KMS encryption or bypass `TenantDataEncryptionService`.
|
|
30
|
+
- Never compare raw feature arrays with exact string checks when wildcard grants apply.
|
|
31
|
+
|
|
32
|
+
## Validation Commands
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
yarn db:generate
|
|
36
|
+
yarn generate
|
|
37
|
+
yarn workspace @open-mercato/core build
|
|
38
|
+
yarn workspace @open-mercato/core test
|
|
39
|
+
```
|
|
40
|
+
|
|
5
41
|
## Core Modules
|
|
6
42
|
|
|
7
43
|
| Module | Path | Description |
|
|
@@ -593,7 +629,7 @@ const crud = makeCrudRoute({
|
|
|
593
629
|
})
|
|
594
630
|
```
|
|
595
631
|
|
|
596
|
-
###
|
|
632
|
+
### Response Enricher Rules
|
|
597
633
|
|
|
598
634
|
- MUST implement `enrichMany()` for batch endpoints (prevents N+1 queries)
|
|
599
635
|
- MUST namespace enriched fields with `_moduleName` prefix (e.g. `_example.todoCount`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.6.3-develop.
|
|
3
|
+
"version": "0.6.3-develop.3811.1.be22750402",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -243,16 +243,16 @@
|
|
|
243
243
|
"zod": "^4.4.3"
|
|
244
244
|
},
|
|
245
245
|
"peerDependencies": {
|
|
246
|
-
"@open-mercato/ai-assistant": "0.6.3-develop.
|
|
247
|
-
"@open-mercato/shared": "0.6.3-develop.
|
|
248
|
-
"@open-mercato/ui": "0.6.3-develop.
|
|
246
|
+
"@open-mercato/ai-assistant": "0.6.3-develop.3811.1.be22750402",
|
|
247
|
+
"@open-mercato/shared": "0.6.3-develop.3811.1.be22750402",
|
|
248
|
+
"@open-mercato/ui": "0.6.3-develop.3811.1.be22750402",
|
|
249
249
|
"react": "^19.0.0",
|
|
250
250
|
"react-dom": "^19.0.0"
|
|
251
251
|
},
|
|
252
252
|
"devDependencies": {
|
|
253
|
-
"@open-mercato/ai-assistant": "0.6.3-develop.
|
|
254
|
-
"@open-mercato/shared": "0.6.3-develop.
|
|
255
|
-
"@open-mercato/ui": "0.6.3-develop.
|
|
253
|
+
"@open-mercato/ai-assistant": "0.6.3-develop.3811.1.be22750402",
|
|
254
|
+
"@open-mercato/shared": "0.6.3-develop.3811.1.be22750402",
|
|
255
|
+
"@open-mercato/ui": "0.6.3-develop.3811.1.be22750402",
|
|
256
256
|
"@testing-library/dom": "^10.4.1",
|
|
257
257
|
"@testing-library/jest-dom": "^6.9.1",
|
|
258
258
|
"@testing-library/react": "^16.3.1",
|
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
The auth module handles authentication, authorization, users, roles, and RBAC.
|
|
4
4
|
|
|
5
|
+
## Always
|
|
6
|
+
|
|
7
|
+
1. Hash passwords with `bcryptjs` using cost >= 10.
|
|
8
|
+
2. Use `findWithDecryption` / `findOneWithDecryption` for user queries.
|
|
9
|
+
3. Prefer `requireFeatures` in page/API metadata for access control.
|
|
10
|
+
4. Declare every module feature in `acl.ts` and seed role grants through `setup.ts`.
|
|
11
|
+
5. Use wildcard-aware helpers such as `matchFeature`, `hasFeature`, and `hasAllFeatures` when inspecting raw granted features.
|
|
12
|
+
|
|
13
|
+
## Ask First
|
|
14
|
+
|
|
15
|
+
- Ask before changing session token format, RBAC semantics, wildcard matching, super-admin behavior, or tenant provisioning outputs.
|
|
16
|
+
- Ask before changing login/reset/invitation error messages because auth messages can leak account existence.
|
|
17
|
+
|
|
18
|
+
## Never
|
|
19
|
+
|
|
20
|
+
- Never log credentials, password reset tokens, session tokens, or decrypted user secrets.
|
|
21
|
+
- Never reveal whether an email exists through auth error messages.
|
|
22
|
+
- Never check raw ACL arrays with `includes(...)`, `Set.has(...)`, or ad hoc wildcard logic.
|
|
23
|
+
|
|
24
|
+
## Validation Commands
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
yarn generate
|
|
28
|
+
yarn workspace @open-mercato/core build
|
|
29
|
+
yarn workspace @open-mercato/core test
|
|
30
|
+
```
|
|
31
|
+
|
|
5
32
|
## Data Model
|
|
6
33
|
|
|
7
34
|
- **Users** — system users with credentials, profile, preferences
|
|
@@ -2,14 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
Use the catalog module for products, categories, pricing, variants, and offers.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
|
-
1. **MUST
|
|
7
|
+
1. **MUST use `selectBestPrice` and the resolver pipeline from `lib/pricing.ts`** for pricing logic.
|
|
8
8
|
2. **MUST use the DI token `catalogPricingService`** when resolving prices — ensures overrides take effect
|
|
9
9
|
3. **MUST register custom pricing resolvers** with explicit priority (`registerCatalogPricingResolver(resolver, { priority })`)
|
|
10
10
|
4. **MUST declare widget injections** in `widgets/injection/` and map via `injection-table.ts`
|
|
11
11
|
5. **MUST follow the standard event pattern** in `events.ts` for all CRUD and lifecycle events
|
|
12
12
|
|
|
13
|
+
## Ask First
|
|
14
|
+
|
|
15
|
+
- Ask before changing price-layer precedence, resolver priority semantics, event IDs, or released widget spot IDs.
|
|
16
|
+
- Ask before deleting or changing option schemas that existing variants may reference.
|
|
17
|
+
|
|
18
|
+
## Never
|
|
19
|
+
|
|
20
|
+
- Never reimplement catalog pricing inline.
|
|
21
|
+
- Never delete option schemas while variants reference them.
|
|
22
|
+
- Never bypass `prepareMutation` for catalog AI tools that mutate products, prices, or media.
|
|
23
|
+
|
|
24
|
+
## Validation Commands
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
yarn db:generate
|
|
28
|
+
yarn generate
|
|
29
|
+
yarn workspace @open-mercato/core build
|
|
30
|
+
```
|
|
31
|
+
|
|
13
32
|
## When You Need Pricing Logic
|
|
14
33
|
|
|
15
34
|
1. Resolve `catalogPricingService` from DI
|
|
@@ -2,13 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
Use the currencies module for multi-currency support, exchange rates, and currency conversion.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
7
|
1. **MUST store currency amounts with 4 decimal precision** — never truncate to 2 decimals internally
|
|
8
8
|
2. **MUST use date-based exchange rates** — always resolve rates for the transaction date, not "current" rate
|
|
9
9
|
3. **MUST record both transaction currency and base currency amounts** — dual recording is mandatory for reporting
|
|
10
10
|
4. **MUST calculate realized gains/losses** on payment: `(payment rate - invoice rate) × foreign amount`
|
|
11
|
-
5. **MUST
|
|
11
|
+
5. **MUST keep financial postings atomic** — full transaction rollback on error
|
|
12
|
+
|
|
13
|
+
## Ask First
|
|
14
|
+
|
|
15
|
+
- Ask before changing precision, exchange-rate lookup semantics, realized gain/loss formulas, or financial reporting fields.
|
|
16
|
+
- Ask before changing historical exchange-rate retention behavior.
|
|
17
|
+
|
|
18
|
+
## Never
|
|
19
|
+
|
|
20
|
+
- Never truncate internal currency amounts to 2 decimals.
|
|
21
|
+
- Never hard-delete exchange rate records — rates are historical reference data.
|
|
22
|
+
- Never delete posted transactions or audit-trail entries.
|
|
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
|
## Key Files
|
|
14
33
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Customer-facing identity and portal authentication with a two-tier RBAC model. This module manages customer user accounts, sessions, roles, invitations, and the authentication flow for the customer portal. It is separate from the internal `auth` module, which handles staff authentication.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
7
|
1. **MUST hash passwords with `bcryptjs` (cost >= 10)** — never store plaintext passwords
|
|
8
8
|
2. **MUST return minimal error messages on auth endpoints** — never reveal whether an email exists (use generic "Invalid email or password")
|
|
@@ -10,11 +10,31 @@ Customer-facing identity and portal authentication with a two-tier RBAC model. T
|
|
|
10
10
|
4. **MUST validate all inputs with zod** — schemas live in `data/validators.ts`
|
|
11
11
|
5. **MUST export `openApi`** from every API route file
|
|
12
12
|
6. **MUST scope all queries by `tenantId`** and filter `deletedAt: null` for soft-deleted records
|
|
13
|
-
7. **MUST
|
|
14
|
-
8. **MUST use `
|
|
15
|
-
9. **MUST
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
7. **MUST use `hashForLookup` for email-based lookups** — emails are stored with a deterministic hash for indexed queries
|
|
14
|
+
8. **MUST use `hashToken` for storing session/verification/reset tokens** — raw tokens are never persisted
|
|
15
|
+
9. **MUST emit events via `emitCustomerAccountsEvent`** for all state changes (login, signup, lock, password reset)
|
|
16
|
+
|
|
17
|
+
## Ask First
|
|
18
|
+
|
|
19
|
+
- Ask before changing cookie names, token TTLs, JWT claim shape, rate limits, lockout thresholds, or portal RBAC semantics.
|
|
20
|
+
- Ask before moving customer portal navigation into a different staff IA group.
|
|
21
|
+
- Ask before changing CRM auto-linking behavior.
|
|
22
|
+
|
|
23
|
+
## Never
|
|
24
|
+
|
|
25
|
+
- Never store plaintext passwords or raw tokens.
|
|
26
|
+
- Never reveal whether an email exists.
|
|
27
|
+
- Never expose cross-tenant data — session validation checks tenant match.
|
|
28
|
+
- Never import staff auth services; customer auth is a fully separate identity system.
|
|
29
|
+
- Never use exact `includes(...)` checks for portal wildcard ACL matching.
|
|
30
|
+
|
|
31
|
+
## Validation Commands
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
yarn db:generate
|
|
35
|
+
yarn generate
|
|
36
|
+
yarn workspace @open-mercato/core build
|
|
37
|
+
```
|
|
18
38
|
|
|
19
39
|
## Data Model
|
|
20
40
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**This is the reference CRUD module.** When building new modules, copy patterns from here first.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Always
|
|
6
6
|
|
|
7
7
|
1. **MUST use this module as the template** for new CRUD modules — copy file structure and patterns
|
|
8
8
|
2. **MUST include all standard module files** — use the list below as a checklist
|
|
@@ -11,6 +11,25 @@
|
|
|
11
11
|
5. **MUST capture custom field snapshots** in command `before`/`after` payloads for undo support
|
|
12
12
|
6. **MUST use `useGuardedMutation` for non-`CrudForm` backend writes** (`POST`/`PUT`/`PATCH`/`DELETE`) and pass `retryLastMutation` in injection context
|
|
13
13
|
|
|
14
|
+
## Ask First
|
|
15
|
+
|
|
16
|
+
- Ask before changing this module's reference patterns, standard module-file checklist, or AI mutation policies.
|
|
17
|
+
- Ask before changing customer data model relationships that downstream modules may copy.
|
|
18
|
+
|
|
19
|
+
## Never
|
|
20
|
+
|
|
21
|
+
- Never bypass custom field normalization in CRUD create/update/read responses.
|
|
22
|
+
- Never omit undo snapshots for custom field mutations.
|
|
23
|
+
- Never write backend `POST`/`PUT`/`PATCH`/`DELETE` actions outside `CrudForm` without `useGuardedMutation`.
|
|
24
|
+
|
|
25
|
+
## Validation Commands
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
yarn db:generate
|
|
29
|
+
yarn generate
|
|
30
|
+
yarn workspace @open-mercato/core build
|
|
31
|
+
```
|
|
32
|
+
|
|
14
33
|
## Key Reference Files — Copy From Here
|
|
15
34
|
|
|
16
35
|
| When you need | Copy from |
|
|
@@ -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
|
```
|