@geonosis/oxlint-plugin-biological-architecture 0.4.0 → 1.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.
Files changed (87) hide show
  1. package/README.md +46 -0
  2. package/corpus/.oxlintrc.json +105 -2
  3. package/corpus/atoms/bad-aliased-import.tsx +4 -0
  4. package/corpus/atoms/nested/bad-relative-climb.tsx +4 -0
  5. package/corpus/emits/bad-opaque-budget.ts +13 -0
  6. package/corpus/emits/good-budget-helper.ts +12 -0
  7. package/corpus/emits/retry.ts +10 -0
  8. package/corpus/features/invoice/cells/bad-aliased-cross-feature-cell.tsx +3 -0
  9. package/corpus/features/invoice/cells/bad-aliased-cross-feature-organelle.tsx +11 -0
  10. package/corpus/features/invoice/cells/bad-aliased-cross-feature-tissue.tsx +3 -0
  11. package/corpus/features/invoice/cells/bad-relative-cross-feature-cell.tsx +3 -0
  12. package/corpus/features/invoice/cells/bad-relative-cross-feature-organelle.tsx +12 -0
  13. package/corpus/features/invoice/cells/bad-relative-cross-feature-tissue.tsx +3 -0
  14. package/corpus/features/invoice/cells/good-own-organelle.tsx +10 -0
  15. package/corpus/features/invoice/cells/good-shared-organelle.tsx +10 -0
  16. package/corpus/features/invoice/compounds/bad-aliased-cross-feature-store.tsx +3 -0
  17. package/corpus/features/invoice/compounds/bad-relative-cross-feature-store.tsx +5 -0
  18. package/corpus/features/invoice/organelles/bad-aliased-cross-feature-organelle.tsx +10 -0
  19. package/corpus/features/invoice/tissues/bad-aliased-cross-feature-organelle.tsx +3 -0
  20. package/corpus/features/invoice/tissues/bad-aliased-cross-feature-store.tsx +3 -0
  21. package/corpus/features/invoice/tissues/bad-relative-cross-feature-organelle.tsx +3 -0
  22. package/corpus/features/invoice/tissues/bad-relative-cross-feature-store.tsx +3 -0
  23. package/corpus/integrations/providers/attio/index.ts +1 -0
  24. package/corpus/integrations/providers/dead-cal/index.ts +3 -0
  25. package/corpus/integrations/providers/email-gmail.ts +3 -0
  26. package/corpus/integrations/providers/hubspot/index.ts +1 -0
  27. package/corpus/integrations/registry.ts +9 -0
  28. package/corpus/manifest.json +16 -0
  29. package/corpus/medusa/api/admin/labelled/route.ts +12 -0
  30. package/corpus/medusa/api/admin/orders/route.ts +11 -0
  31. package/corpus/medusa/jobs/index.ts +1 -0
  32. package/corpus/medusa/jobs/reconcile-nightly.ts +7 -0
  33. package/corpus/medusa/modules/catalog/index.ts +7 -0
  34. package/corpus/medusa/modules/search/index.ts +7 -0
  35. package/corpus/medusa/plugins/b2b/src/api/admin/b2b/notes/route.ts +12 -0
  36. package/corpus/medusa/plugins/b2b/src/api/admin/b2b/orders/route.ts +9 -0
  37. package/corpus/medusa/plugins/b2b/src/api/admin/b2b/quotes/route.ts +6 -0
  38. package/corpus/medusa/plugins/b2b/src/api/hooks/stripe/route.ts +3 -0
  39. package/corpus/medusa/plugins/b2b/src/api/store/b2b/companies/route.ts +6 -0
  40. package/corpus/medusa/plugins/b2b/src/api/store/route.ts +3 -0
  41. package/corpus/medusa/subscribers/bad-inferred-id.ts +7 -0
  42. package/corpus/medusa/subscribers/good-declared-id.ts +10 -0
  43. package/corpus/medusa/subscribers/index.ts +10 -0
  44. package/corpus/medusa/workflows/bad-duplicate-query-step.ts +8 -0
  45. package/corpus/medusa/workflows/bad-place-order.ts +7 -0
  46. package/corpus/medusa/workflows/bad-shared-query-step-name.ts +8 -0
  47. package/corpus/medusa/workflows/bad-unnamed-when.ts +7 -0
  48. package/corpus/medusa/workflows/good-flagged-step.ts +10 -0
  49. package/corpus/medusa/workflows/good-named-query-steps.ts +8 -0
  50. package/corpus/medusa/workflows/good-named-when.ts +7 -0
  51. package/corpus/medusa/workflows/good-place-order.ts +15 -0
  52. package/corpus/medusa/workflows/good-single-query-step.ts +7 -0
  53. package/corpus/molecules/bad-aliased-cell-import.tsx +3 -0
  54. package/corpus/molecules/nested/bad-relative-climb.tsx +3 -0
  55. package/corpus/testbed/__tests__/integration/checkout/tests.ts +11 -0
  56. package/corpus/testbed/__tests__/integration/orders/tests.ts +9 -0
  57. package/corpus/testbed/__tests__/unit/checkout/tests.ts +10 -0
  58. package/corpus/tokens/bad-arbitrary-class.tsx +3 -0
  59. package/corpus/tokens/bad-asserted-style.tsx +5 -0
  60. package/corpus/tokens/bad-font-literal.tsx +5 -0
  61. package/corpus/tokens/bad-font-undeclared-role.tsx +3 -0
  62. package/corpus/tokens/bad-foreign-variable.tsx +3 -0
  63. package/corpus/tokens/bad-literal-style.tsx +3 -0
  64. package/corpus/tokens/bad-shorthand-style.tsx +5 -0
  65. package/corpus/tokens/good-arbitrary-non-color.tsx +3 -0
  66. package/corpus/tokens/good-font-role.tsx +5 -0
  67. package/corpus/tokens/good-local-variable.tsx +11 -0
  68. package/corpus/tokens/good-token-style.tsx +8 -0
  69. package/corpus/tokens/order-status.tsx +217 -0
  70. package/corpus/tokens/theme/palette.tsx +7 -0
  71. package/corpus/trpc/routers/_app.ts +2 -0
  72. package/corpus/trpc/routers/documents-mounted.ts +7 -0
  73. package/corpus/trpc/routers/health.ts +3 -0
  74. package/corpus/trpc/routers/orphan.ts +2 -0
  75. package/corpus/trpc/routers/vault.ts +3 -0
  76. package/corpus/trpc/schemas/health.ts +1 -0
  77. package/corpus/trpc/schemas/index.ts +1 -0
  78. package/corpus/trpc/schemas/invoice.ts +1 -0
  79. package/corpus/trpc/schemas/purchase-order.ts +1 -0
  80. package/corpus/trpc/schemas/unserved.ts +2 -0
  81. package/corpus/trpc/schemas/vault.ts +1 -0
  82. package/dist/{chunk-55NK7NJN.js → chunk-UVENNNFM.js} +23 -1
  83. package/dist/index.d.ts +12 -0
  84. package/dist/index.js +1705 -16
  85. package/dist/presets.d.ts +12 -0
  86. package/dist/presets.js +1 -1
  87. package/package.json +2 -2
package/README.md CHANGED
@@ -135,6 +135,7 @@ months. Carry these across, or turn the rule off:
135
135
  | --- | --- | --- |
136
136
  | `no-brand-names` | `{ brands, allowedSubstrings }` | refuses the run |
137
137
  | `organelle-dependency` | `{ sharedFeatures }` | only `shared` crosses a feature boundary |
138
+ | `cell-no-cross-feature-organelles` | `{ sharedFeatures }` | only `shared` crosses a feature boundary |
138
139
  | `documents-share-one-table` | `{ perKindTables }` | refuses the run |
139
140
  | `document-sagas-are-generic` | `{ perKindPrefixes }` | refuses the run |
140
141
  | `step-opens-its-own-cell` | `{ engine, within, wrapper }` | refuses the run |
@@ -153,6 +154,51 @@ Two more facts a fork's config will trip on:
153
154
  namespace is the plugin's identity, not the package's, so renaming or re-scoping the package does
154
155
  not rename a single rule id in a single consumer config.
155
156
 
157
+ ### Last step of every bump — `geonosis-doctor`
158
+
159
+ ```bash
160
+ pnpm add -D @geonosis/doctor
161
+ npx geonosis-doctor
162
+ ```
163
+
164
+ It answers everything below for every config in the tree, and three more questions besides — see
165
+ [`@geonosis/doctor`](https://www.npmjs.com/package/@geonosis/doctor). Run it after every bump and in
166
+ CI. What follows is the reasoning it automates, kept because a check nobody understands is a check
167
+ nobody trusts.
168
+
169
+ #### Why: declared is not loaded
170
+
171
+ **Declared is not loaded.** oxlint resolves a `jsPlugins` specifier from the CONFIG FILE's
172
+ directory, so a nested `apps/<ws>/node_modules/@geonosis/…` left behind at the old version means
173
+ oxlint runs the OLD plugin while every `package.json` and the lockfile say the new one. bun leaves
174
+ a nested copy when a per-workspace `bun add` runs and the root already has one; one consumer measured
175
+ a whole bug report against 0.3.0 that way, on a repo pinned to 0.4.0.
176
+
177
+ The check that is true on every package manager is the one that asks the resolver, from **each
178
+ workspace directory** — this is what oxlint would load:
179
+
180
+ ```bash
181
+ node --input-type=module -e \
182
+ 'const p = (await import("@geonosis/oxlint-plugin-biological-architecture")).default; console.log(p.meta.version)'
183
+ ```
184
+
185
+ It must print the pinned version. Every published version of this plugin carries `meta.version`, so
186
+ there is no version of it this check cannot read.
187
+
188
+ Then find the stray copy, and mind that the answer is package-manager-specific:
189
+
190
+ - **bun / npm** — real directories, so counting them is meaningful:
191
+ ```bash
192
+ find . -path "*@geonosis/oxlint-plugin-biological-architecture/package.json" -not -path "*/.git/*"
193
+ ```
194
+ More than one is the bug. Fix with
195
+ `rm -rf apps/*/node_modules/@geonosis packages/*/node_modules/@geonosis && bun install` — no flags,
196
+ and never `--ignore-scripts` over the whole tree.
197
+ - **pnpm** — `node_modules/@geonosis/*` are SYMLINKS into `.pnpm/`, which keeps every version ever
198
+ installed. The same `find` answers 7 on a tree that is perfectly correct, and 0 if you exclude
199
+ `.pnpm`. Read the links instead: `ls -l node_modules/@geonosis` in each workspace, and check the
200
+ version in the target path.
201
+
156
202
  ## Where to read on
157
203
 
158
204
  - `RULES.md` — every rule, its preset, which source tree it came from, and how each divergence was
@@ -11,6 +11,14 @@
11
11
  "biological-architecture/atom-no-deps": "error",
12
12
  "biological-architecture/cell-must-be-stateful": "error",
13
13
  "biological-architecture/cell-must-not-compose-cell": "error",
14
+ "biological-architecture/cell-no-cross-feature-organelles": [
15
+ "error",
16
+ {
17
+ "sharedFeatures": [
18
+ "shared"
19
+ ]
20
+ }
21
+ ],
14
22
  "biological-architecture/cell-no-tissues": "error",
15
23
  "biological-architecture/cells-folder-index-is-barrel": "error",
16
24
  "biological-architecture/compound-must-be-stateless": "error",
@@ -35,7 +43,14 @@
35
43
  }
36
44
  ],
37
45
  "biological-architecture/effect-hook-naming": "error",
38
- "biological-architecture/emit-declares-attempts": "error",
46
+ "biological-architecture/emit-declares-attempts": [
47
+ "error",
48
+ {
49
+ "budgetHelpers": [
50
+ "retryableEvent"
51
+ ]
52
+ }
53
+ ],
39
54
  "biological-architecture/layer-walls": [
40
55
  "error",
41
56
  {
@@ -72,6 +87,8 @@
72
87
  "biological-architecture/max-comment-density": "error",
73
88
  "biological-architecture/molecule-atoms-only": "error",
74
89
  "biological-architecture/molecule-must-compose": "error",
90
+ "biological-architecture/mutating-step-declares-retry": "error",
91
+ "biological-architecture/named-when-block": "error",
75
92
  "biological-architecture/next-route-segment-is-thin-delegate": "error",
76
93
  "biological-architecture/no-brand-names": [
77
94
  "error",
@@ -89,10 +106,26 @@
89
106
  "biological-architecture/no-d1-transaction": "error",
90
107
  "biological-architecture/no-duplicate-jsx-patterns": "error",
91
108
  "biological-architecture/no-hook-in-component-disguise": "error",
109
+ "biological-architecture/no-index-count-as-exact": "error",
92
110
  "biological-architecture/no-inert-hidden-jsx": "error",
93
111
  "biological-architecture/no-inline-data-in-jsx": "error",
94
112
  "biological-architecture/no-invalid-feature-folders": "error",
113
+ "biological-architecture/no-loader-side-effect-in-index-file": "error",
95
114
  "biological-architecture/no-logic-in-component-files": "error",
115
+ "biological-architecture/no-mock-db-in-integration": [
116
+ "error",
117
+ {
118
+ "dbModules": [
119
+ "@fixture/db"
120
+ ],
121
+ "integrationDirs": [
122
+ "__tests__/integration"
123
+ ],
124
+ "mockNames": [
125
+ "mockDb"
126
+ ]
127
+ }
128
+ ],
96
129
  "biological-architecture/no-orm-outside-db": "error",
97
130
  "biological-architecture/no-raw-html-atoms": [
98
131
  "error",
@@ -111,6 +144,18 @@
111
144
  "biological-architecture/no-trivial-wrapper-component": "error",
112
145
  "biological-architecture/no-ts-in-bio-folders": "error",
113
146
  "biological-architecture/no-type-definitions-in-components": "error",
147
+ "biological-architecture/no-unregistered-plugin-dir": [
148
+ "error",
149
+ {
150
+ "roots": [
151
+ "integrations/providers"
152
+ ],
153
+ "registry": "integrations/registry.ts",
154
+ "manifests": [
155
+ "index.ts"
156
+ ]
157
+ }
158
+ ],
114
159
  "biological-architecture/no-void-port": "error",
115
160
  "biological-architecture/organelle-dependency": [
116
161
  "error",
@@ -121,10 +166,42 @@
121
166
  }
122
167
  ],
123
168
  "biological-architecture/organelle-single-source": "error",
169
+ "biological-architecture/plugin-route-namespaced": [
170
+ "error",
171
+ {
172
+ "packages": [
173
+ {
174
+ "under": "medusa/plugins",
175
+ "name": "@acme/{dir}",
176
+ "namespaced": true
177
+ }
178
+ ]
179
+ }
180
+ ],
124
181
  "biological-architecture/queries-require-org-scope": "error",
125
182
  "biological-architecture/queue-loop-is-the-library": "error",
183
+ "biological-architecture/route-no-inline-mutation": "error",
184
+ "biological-architecture/router-schema-parity": [
185
+ "error",
186
+ {
187
+ "routers": "trpc/routers",
188
+ "schemas": "trpc/schemas",
189
+ "ignore": [
190
+ "_app",
191
+ "index"
192
+ ],
193
+ "mounts": {
194
+ "documents-mounted": [
195
+ "invoice",
196
+ "purchase-order"
197
+ ]
198
+ }
199
+ }
200
+ ],
201
+ "biological-architecture/service-name-not-reserved": "error",
126
202
  "biological-architecture/ssot-no-inline-facts": "error",
127
203
  "biological-architecture/ssot-no-process-env": "error",
204
+ "biological-architecture/step-declares-compensation-or-none": "error",
128
205
  "biological-architecture/step-opens-its-own-cell": [
129
206
  "error",
130
207
  {
@@ -134,6 +211,7 @@
134
211
  }
135
212
  ],
136
213
  "biological-architecture/store-route-scopes-tenant-data": "error",
214
+ "biological-architecture/subscriber-declares-id": "error",
137
215
  "biological-architecture/tables-declare-their-plane": "error",
138
216
  "biological-architecture/tenant-tables-carry-org-id": "error",
139
217
  "biological-architecture/time-through-the-door": "error",
@@ -142,7 +220,32 @@
142
220
  "biological-architecture/tissue-no-hooks": "error",
143
221
  "biological-architecture/tissue-no-organelles": "error",
144
222
  "biological-architecture/tissue-no-stores": "error",
223
+ "biological-architecture/unique-query-step-name": "error",
145
224
  "biological-architecture/worker-handles-are-scoped": "error",
146
- "biological-architecture/zustand-v5-best-practices": "error"
225
+ "biological-architecture/zustand-v5-best-practices": "error",
226
+ "biological-architecture/font-roles-only": [
227
+ "error",
228
+ {
229
+ "roles": [
230
+ "body",
231
+ "display"
232
+ ],
233
+ "allow": [
234
+ "__fixtures__/tokens/theme/"
235
+ ]
236
+ }
237
+ ],
238
+ "biological-architecture/tokens-only-colors": [
239
+ "error",
240
+ {
241
+ "tokenPrefix": [
242
+ "--mc-",
243
+ "--theme-"
244
+ ],
245
+ "allow": [
246
+ "__fixtures__/tokens/theme/"
247
+ ]
248
+ }
249
+ ]
147
250
  }
148
251
  }
@@ -0,0 +1,4 @@
1
+ // The same breach through the bundler alias — the spelling the corpus never carried for this rule.
2
+ import { Field } from '@kit/ui/molecules/field'
3
+
4
+ export const BadAliasedImport = Field
@@ -0,0 +1,4 @@
1
+ // A climb, not a sibling: the source names the tier only two directories up.
2
+ import { Field } from '../../molecules/field'
3
+
4
+ export const BadRelativeClimb = Field
@@ -0,0 +1,13 @@
1
+ import { emitEventStep } from '@medusajs/medusa/core-flows'
2
+
3
+ import { withDefaults } from './retry'
4
+
5
+ // A call the repo has NOT named as a budget builder. Nothing here can tell whether it produces
6
+ // `attempts > 1`, and before `budgetHelpers` existed this passed silently along with every other
7
+ // helper call — which is how a workspace of 54 wrapped emits got zero findings and no coverage.
8
+ export const emitCacheWarmed = (data: { key: string }) =>
9
+ emitEventStep({
10
+ data,
11
+ eventName: 'cache.warmed',
12
+ options: withDefaults({ priority: 10 }),
13
+ })
@@ -0,0 +1,12 @@
1
+ import { emitEventStep } from '@medusajs/medusa/core-flows'
2
+
3
+ import { retryableEvent } from './retry'
4
+
5
+ // The shape the consumer actually writes: all 54 of its emit sites go through this helper, which
6
+ // throws on `attempts <= 1`. Named in `budgetHelpers`, so the call IS a budget.
7
+ export const emitQuoteAccepted = (data: { quote_id: string }) =>
8
+ emitEventStep({
9
+ data,
10
+ eventName: 'quote.accepted',
11
+ options: retryableEvent({ priority: 10 }),
12
+ })
@@ -1,3 +1,13 @@
1
1
  // The shared retry budgets. One place, so a change to what "background" means reaches every emit.
2
2
  export const RETRY_BACKGROUND = { attempts: 5, backoff: 2000 }
3
3
  export const RETRY_CRITICAL = { attempts: 9, backoff: 500 }
4
+
5
+ // The budget builder, which throws on `attempts <= 1` — naming it in `budgetHelpers` is what turns
6
+ // a call the rule cannot read into a call it can accept.
7
+ export const retryableEvent = (options: Record<string, unknown> = {}) => ({
8
+ attempts: RETRY_BACKGROUND.attempts,
9
+ ...options,
10
+ })
11
+
12
+ // A wrapper that is NOT a budget builder.
13
+ export const withDefaults = (options: Record<string, unknown> = {}) => ({ ...options })
@@ -0,0 +1,3 @@
1
+ import { BillingEditor } from '@/features/billing/cells/billing-editor'
2
+
3
+ export const BadAliasedCrossFeatureCell = BillingEditor
@@ -0,0 +1,11 @@
1
+ // The same breach spelled through the bundler alias. Where the import LANDS is the fact; the two
2
+ // spellings must read alike.
3
+ import { useState } from 'react'
4
+
5
+ import { BillingTotals } from '@/features/billing/organelles/billing-totals'
6
+
7
+ export function BadAliasedCrossFeatureOrganelle() {
8
+ const [open] = useState(false)
9
+
10
+ return <section>{open ? <BillingTotals /> : null}</section>
11
+ }
@@ -0,0 +1,3 @@
1
+ import { BillingPage } from '@/features/billing/tissues/billing-page'
2
+
3
+ export const BadAliasedCrossFeatureTissue = BillingPage
@@ -0,0 +1,3 @@
1
+ import { BillingEditor } from '../../billing/cells/billing-editor'
2
+
3
+ export const BadRelativeCrossFeatureCell = BillingEditor
@@ -0,0 +1,12 @@
1
+ // A cell climbing out of its feature into ANOTHER feature's organelle — the state compartment of a
2
+ // feature this one does not own. organelle-dependency polices organelles/ and no-cross-feature-stores
3
+ // polices stores, so until cell-no-cross-feature-organelles nothing here fired at all.
4
+ import { useState } from 'react'
5
+
6
+ import { BillingTotals } from '../../billing/organelles/billing-totals'
7
+
8
+ export function BadRelativeCrossFeatureOrganelle() {
9
+ const [open] = useState(false)
10
+
11
+ return <section>{open ? <BillingTotals /> : null}</section>
12
+ }
@@ -0,0 +1,3 @@
1
+ import { BillingPage } from '../../billing/tissues/billing-page'
2
+
3
+ export const BadRelativeCrossFeatureTissue = BillingPage
@@ -0,0 +1,10 @@
1
+ // A cell hosting its OWN feature's organelle — the whole point of a cell.
2
+ import { useState } from 'react'
3
+
4
+ import { InvoiceLines } from '../organelles/invoice-lines'
5
+
6
+ export function GoodOwnOrganelle() {
7
+ const [open] = useState(false)
8
+
9
+ return <section>{open ? <InvoiceLines /> : null}</section>
10
+ }
@@ -0,0 +1,10 @@
1
+ // The shared feature is infrastructure every feature may read, which is what sharedFeatures names.
2
+ import { useState } from 'react'
3
+
4
+ import { SaveIndicator } from '@/features/shared/organelles/save-indicator'
5
+
6
+ export function GoodSharedOrganelle() {
7
+ const [open] = useState(false)
8
+
9
+ return <section>{open ? <SaveIndicator /> : null}</section>
10
+ }
@@ -0,0 +1,3 @@
1
+ import { useBillingStore } from '@/features/billing/stores/billing-store'
2
+
3
+ export const BadAliasedCrossFeatureStore = useBillingStore
@@ -0,0 +1,5 @@
1
+ // A compound climbing into another feature's store. The string names no feature until it is
2
+ // resolved against this file.
3
+ import { useBillingStore } from '../../billing/stores/billing-store'
4
+
5
+ export const BadRelativeCrossFeatureStore = useBillingStore
@@ -0,0 +1,10 @@
1
+ // The aliased twin of bad-relative-cross-feature-organelle.tsx: one breach, two spellings.
2
+ import { BillingTotals } from '@/features/billing/organelles/billing-totals'
3
+
4
+ export function BadAliasedCrossFeatureOrganelle() {
5
+ return (
6
+ <section>
7
+ <BillingTotals />
8
+ </section>
9
+ )
10
+ }
@@ -0,0 +1,3 @@
1
+ import { BillingTotals } from '@/features/billing/organelles/billing-totals'
2
+
3
+ export const BadAliasedCrossFeatureOrganelle = BillingTotals
@@ -0,0 +1,3 @@
1
+ import { useBillingStore } from '@/features/billing/stores/billing-store'
2
+
3
+ export const BadAliasedCrossFeatureStore = useBillingStore
@@ -0,0 +1,3 @@
1
+ import { BillingTotals } from '../../billing/organelles/billing-totals'
2
+
3
+ export const BadRelativeCrossFeatureOrganelle = BillingTotals
@@ -0,0 +1,3 @@
1
+ import { useBillingStore } from '../../billing/stores/billing-store'
2
+
3
+ export const BadRelativeCrossFeatureStore = useBillingStore
@@ -0,0 +1 @@
1
+ export const AttioProvider = { id: 'cp_attio' }
@@ -0,0 +1,3 @@
1
+ // Named nowhere in the registry beside it. Ships a manifest, is reached by nothing, and reads as
2
+ // an integration to anyone counting directories. Midday carries eight of these.
3
+ export const CalProvider = { id: 'cp_cal' }
@@ -0,0 +1,3 @@
1
+ // A provider that is a FILE, not a directory — dielime's messaging seam. Out of scope because
2
+ // nothing matches `<root>/<dir>/<manifest>`, not because of a special case.
3
+ export const emailGmail = { channel: 'email' }
@@ -0,0 +1 @@
1
+ export const HubspotProvider = { id: 'cp_hubspot' }
@@ -0,0 +1,9 @@
1
+ import { AttioProvider } from './providers/attio/index'
2
+
3
+ // Two of the three directories beside this file are named here. The third is `dead-cal`, which
4
+ // ships a manifest, is imported by nothing, and reads as an integration to anyone counting
5
+ // directories — Midday carries eight of these.
6
+ export const providers = {
7
+ cp_attio: AttioProvider,
8
+ cp_hubspot: 'providers/hubspot',
9
+ }
@@ -4,6 +4,7 @@
4
4
  "biological-architecture/atom-no-deps",
5
5
  "biological-architecture/cell-must-be-stateful",
6
6
  "biological-architecture/cell-must-not-compose-cell",
7
+ "biological-architecture/cell-no-cross-feature-organelles",
7
8
  "biological-architecture/cell-no-tissues",
8
9
  "biological-architecture/cells-folder-index-is-barrel",
9
10
  "biological-architecture/compound-must-be-stateless",
@@ -14,10 +15,13 @@
14
15
  "biological-architecture/documents-share-one-table",
15
16
  "biological-architecture/effect-hook-naming",
16
17
  "biological-architecture/emit-declares-attempts",
18
+ "biological-architecture/font-roles-only",
17
19
  "biological-architecture/layer-walls",
18
20
  "biological-architecture/max-comment-density",
19
21
  "biological-architecture/molecule-atoms-only",
20
22
  "biological-architecture/molecule-must-compose",
23
+ "biological-architecture/mutating-step-declares-retry",
24
+ "biological-architecture/named-when-block",
21
25
  "biological-architecture/next-route-segment-is-thin-delegate",
22
26
  "biological-architecture/no-brand-names",
23
27
  "biological-architecture/no-card-shaped-div",
@@ -25,10 +29,13 @@
25
29
  "biological-architecture/no-d1-transaction",
26
30
  "biological-architecture/no-duplicate-jsx-patterns",
27
31
  "biological-architecture/no-hook-in-component-disguise",
32
+ "biological-architecture/no-index-count-as-exact",
28
33
  "biological-architecture/no-inert-hidden-jsx",
29
34
  "biological-architecture/no-inline-data-in-jsx",
30
35
  "biological-architecture/no-invalid-feature-folders",
36
+ "biological-architecture/no-loader-side-effect-in-index-file",
31
37
  "biological-architecture/no-logic-in-component-files",
38
+ "biological-architecture/no-mock-db-in-integration",
32
39
  "biological-architecture/no-orm-outside-db",
33
40
  "biological-architecture/no-raw-html-atoms",
34
41
  "biological-architecture/no-raw-sql-outside-allowed",
@@ -38,15 +45,22 @@
38
45
  "biological-architecture/no-trivial-wrapper-component",
39
46
  "biological-architecture/no-ts-in-bio-folders",
40
47
  "biological-architecture/no-type-definitions-in-components",
48
+ "biological-architecture/no-unregistered-plugin-dir",
41
49
  "biological-architecture/no-void-port",
42
50
  "biological-architecture/organelle-dependency",
43
51
  "biological-architecture/organelle-single-source",
52
+ "biological-architecture/plugin-route-namespaced",
44
53
  "biological-architecture/queries-require-org-scope",
45
54
  "biological-architecture/queue-loop-is-the-library",
55
+ "biological-architecture/route-no-inline-mutation",
56
+ "biological-architecture/router-schema-parity",
57
+ "biological-architecture/service-name-not-reserved",
46
58
  "biological-architecture/ssot-no-inline-facts",
47
59
  "biological-architecture/ssot-no-process-env",
60
+ "biological-architecture/step-declares-compensation-or-none",
48
61
  "biological-architecture/step-opens-its-own-cell",
49
62
  "biological-architecture/store-route-scopes-tenant-data",
63
+ "biological-architecture/subscriber-declares-id",
50
64
  "biological-architecture/tables-declare-their-plane",
51
65
  "biological-architecture/tenant-tables-carry-org-id",
52
66
  "biological-architecture/time-through-the-door",
@@ -55,6 +69,8 @@
55
69
  "biological-architecture/tissue-no-hooks",
56
70
  "biological-architecture/tissue-no-organelles",
57
71
  "biological-architecture/tissue-no-stores",
72
+ "biological-architecture/tokens-only-colors",
73
+ "biological-architecture/unique-query-step-name",
58
74
  "biological-architecture/worker-handles-are-scoped",
59
75
  "biological-architecture/zustand-v5-best-practices"
60
76
  ]
@@ -0,0 +1,12 @@
1
+ export async function GET(req, res) {
2
+ const query = req.scope.resolve('query')
3
+ const { data: orders, metadata } = await query.index({ entity: 'order' })
4
+
5
+ res.json({
6
+ count: metadata?.estimate_count ?? orders.length,
7
+ count_is_estimate: true,
8
+ limit: 20,
9
+ offset: 0,
10
+ orders,
11
+ })
12
+ }
@@ -0,0 +1,11 @@
1
+ export async function GET(req, res) {
2
+ const query = req.scope.resolve('query')
3
+ const { data: orders, metadata } = await query.index({ entity: 'order' })
4
+
5
+ res.json({
6
+ count: metadata?.estimate_count ?? orders.length,
7
+ limit: 20,
8
+ offset: 0,
9
+ orders,
10
+ })
11
+ }
@@ -0,0 +1 @@
1
+ export * from './reconcile-nightly'
@@ -0,0 +1,7 @@
1
+ export default async function reconcileNightly(container) {
2
+ const ledger = container.resolve('ledger')
3
+
4
+ await ledger.reconcile()
5
+ }
6
+
7
+ export const config = { name: 'reconcile-nightly', schedule: '0 2 * * *' }
@@ -0,0 +1,7 @@
1
+ import { Module } from '@medusajs/framework/utils'
2
+
3
+ import { CatalogSearchModuleService } from './service'
4
+
5
+ export const SERVICE_NAME = 'catalog_search'
6
+
7
+ export default Module(SERVICE_NAME, { service: CatalogSearchModuleService })
@@ -0,0 +1,7 @@
1
+ import { Module } from '@medusajs/framework/utils'
2
+
3
+ import { SearchModuleService } from './service'
4
+
5
+ export const SERVICE_NAME = 'search'
6
+
7
+ export default Module(SERVICE_NAME, { service: SearchModuleService })
@@ -0,0 +1,12 @@
1
+ export async function POST(req, res) {
2
+ const conversations = req.scope.resolve('ai')
3
+
4
+ // arch:inline-mutation-ok(model-name patch-up on the row this handler just created)
5
+ await (
6
+ conversations as unknown as {
7
+ updateAiConversations: (data: Record<string, unknown>) => Promise<unknown>
8
+ }
9
+ ).updateAiConversations({ id: req.params.id, model: req.validatedBody.model })
10
+
11
+ res.json({ ok: true })
12
+ }
@@ -0,0 +1,9 @@
1
+ import { placeOrderWorkflow } from '../../../../workflows/place-order'
2
+
3
+ export async function POST(req, res) {
4
+ const { result } = await placeOrderWorkflow(req.scope).run({ input: req.validatedBody })
5
+ const quotes = req.scope.resolve('quote')
6
+ const existing = await quotes.listQuotes({}, { take: 5 })
7
+
8
+ res.json({ existing, result })
9
+ }
@@ -0,0 +1,6 @@
1
+ export async function POST(req, res) {
2
+ const quotes = req.scope.resolve('quote')
3
+ const quote = await quotes.createQuotes(req.validatedBody)
4
+
5
+ res.json({ quote })
6
+ }
@@ -0,0 +1,3 @@
1
+ export async function POST(req, res) {
2
+ res.json({ received: true })
3
+ }
@@ -0,0 +1,6 @@
1
+ export async function GET(req, res) {
2
+ const query = req.scope.resolve('query')
3
+ const { data: companies } = await query.graph({ entity: 'company' })
4
+
5
+ res.json({ companies })
6
+ }
@@ -0,0 +1,3 @@
1
+ export async function GET(req, res) {
2
+ res.json({ ok: true })
3
+ }
@@ -0,0 +1,7 @@
1
+ export default async function orderPlaced({ event, container }) {
2
+ const notifications = container.resolve('notification')
3
+
4
+ await notifications.createNotifications({ to: event.data.email })
5
+ }
6
+
7
+ export const config = { event: 'order.placed' }
@@ -0,0 +1,10 @@
1
+ export default async function orderShipped({ event, container }) {
2
+ const notifications = container.resolve('notification')
3
+
4
+ await notifications.createNotifications({ to: event.data.email })
5
+ }
6
+
7
+ export const config = {
8
+ context: { subscriberId: 'order-shipped-notify' },
9
+ event: 'order.shipped',
10
+ }
@@ -0,0 +1,10 @@
1
+ export default async function orderCancelled({ event, container }) {
2
+ const notifications = container.resolve('notification')
3
+
4
+ await notifications.createNotifications({ to: event.data.email })
5
+ }
6
+
7
+ export const config = {
8
+ context: { subscriberId: 'order-cancelled-notify' },
9
+ event: 'order.cancelled',
10
+ }
@@ -0,0 +1,8 @@
1
+ import { createWorkflow, useQueryGraphStep, WorkflowResponse } from '@medusajs/framework/workflows-sdk'
2
+
3
+ export const readTwice = createWorkflow('read-twice', () => {
4
+ const customer = useQueryGraphStep({ entity: 'customer' }).config({ name: 'get-customer' })
5
+ const orders = useQueryGraphStep({ entity: 'order' })
6
+
7
+ return new WorkflowResponse({ customer, orders })
8
+ })