toga-ai 1.0.146 → 1.0.148
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/knowledge/CONVENTIONS.md +12 -6
- package/knowledge/clients/compass-canada/INDEX.md +1 -0
- package/knowledge/clients/compass-canada/features/grand-and-toy-asn-import.md +105 -0
- package/knowledge/clients/compass-canada/profile.md +12 -5
- package/knowledge/standalone/apps/togatech/features/seo-aeo-geo-prerender.md +9 -5
- package/package.json +1 -1
package/knowledge/CONVENTIONS.md
CHANGED
|
@@ -8,10 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
## The two axes
|
|
10
10
|
|
|
11
|
-
1. **Framework first.** Everything app- or framework-related lives under `1.0
|
|
12
|
-
`2.0
|
|
13
|
-
- **1.0** — the `App_` framework; core repo **`library`**.
|
|
14
|
-
- **2.0** — the `_underscore` framework; core repo **`_underscore`**.
|
|
11
|
+
1. **Framework first.** Everything app- or framework-related lives under `1.0/`,
|
|
12
|
+
`2.0/`, or `standalone/`:
|
|
13
|
+
- **1.0** — the `App_` PHP framework; core repo **`library`**.
|
|
14
|
+
- **2.0** — the `_underscore` PHP framework; core repo **`_underscore`**.
|
|
15
|
+
- **standalone** — apps that belong to **no** PHP framework (e.g. `togatech`, a React/TS
|
|
16
|
+
site; `forward`). They live under `standalone/apps/<repo>/`, have **no framework core**,
|
|
17
|
+
and depend on nothing implicitly. Not everything is 1.0 or 2.0.
|
|
15
18
|
2. **Shared vs. client.** Within a framework, app/feature/architecture knowledge
|
|
16
19
|
lives under `apps/<repo>/`. Anything specific to a single client lives at the top
|
|
17
20
|
level under `clients/<client>/` and tags its `framework` in frontmatter.
|
|
@@ -29,6 +32,8 @@ knowledge/
|
|
|
29
32
|
├── 2.0/
|
|
30
33
|
│ ├── apps/<repo>/architecture.md + features/*.md + workflows/*.md
|
|
31
34
|
│ └── standards/*.md # 2.0 coding standards (_underscore)
|
|
35
|
+
├── standalone/
|
|
36
|
+
│ └── apps/<repo>/architecture.md + features/*.md # non-PHP apps (e.g. togatech); no core
|
|
32
37
|
└── clients/<client>/
|
|
33
38
|
├── profile.md
|
|
34
39
|
├── features/*.md # client-specific feature overrides (link back to apps/)
|
|
@@ -49,13 +54,14 @@ The shared identity/topology of every repo. Maintained **only by the skills**.
|
|
|
49
54
|
|
|
50
55
|
- `repo` — on-disk repo/folder name (the key; unique).
|
|
51
56
|
- `project` — logical project name.
|
|
52
|
-
- `framework` — `"1.0"` or `"
|
|
57
|
+
- `framework` — `"1.0"`, `"2.0"`, or `"standalone"` (non-PHP apps with no framework core).
|
|
53
58
|
- `role` — `"core"` (the framework base every same-framework repo depends on) or `"app"`.
|
|
54
59
|
- `dependsOn` — additional repos this one depends on beyond the framework core
|
|
55
60
|
(e.g. `api2` may later depend on `apiproxy`).
|
|
56
61
|
|
|
57
62
|
**Dependency loading:** every repo implicitly depends on its framework's `core` repo
|
|
58
|
-
(`_underscore` for 2.0, `library` for 1.0), plus any transitive `dependsOn`.
|
|
63
|
+
(`_underscore` for 2.0, `library` for 1.0), plus any transitive `dependsOn`. `standalone`
|
|
64
|
+
apps have no framework core, so they load only themselves plus any explicit `dependsOn`.
|
|
59
65
|
`node knowledge.js deps --repo=<repo>` resolves the full load order.
|
|
60
66
|
|
|
61
67
|
## Client app-scope (`apps:` on `profile.md`)
|
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
5
|
+
| [Grand & Toy ASN Import (Compass Canada)](features/grand-and-toy-asn-import.md) | 2.0 | Imports Grand & Toy (G&T) Advance Shipping Notices for Compass Canada. | worker/crons/toga2/compasscanada/workflow/4_import_grand_and_toy_advance_shipping_notices.php, worker/crons/toga2/compasscanada/workflow/import_grand_and_toy_asn_from_file.php, worker/schedules/cron.worker.sync.json, _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Model/Compass/Canada/AdvanceShippingNotice.php, dbchanges2/Client_CompassCanada/ |
|
|
5
6
|
| [Compass Canada](profile.md) | 2.0 | Compass Canada is the Canadian arm of the Compass account — a separate TOGA tenant, related to but distinct from Compass USA. | |
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Grand & Toy ASN Import (Compass Canada)
|
|
3
|
+
framework: "2.0"
|
|
4
|
+
project: _Underscore
|
|
5
|
+
client: compass-canada
|
|
6
|
+
type: client-feature
|
|
7
|
+
status: active
|
|
8
|
+
updated: 2026-06-19
|
|
9
|
+
owners: ["bala"]
|
|
10
|
+
files:
|
|
11
|
+
- worker/crons/toga2/compasscanada/workflow/4_import_grand_and_toy_advance_shipping_notices.php
|
|
12
|
+
- worker/crons/toga2/compasscanada/workflow/import_grand_and_toy_asn_from_file.php
|
|
13
|
+
- worker/schedules/cron.worker.sync.json
|
|
14
|
+
- _underscore/Model/Compass/AdvanceShippingNotice.php
|
|
15
|
+
- _underscore/Model/Compass/Canada/AdvanceShippingNotice.php
|
|
16
|
+
- dbchanges2/Client_CompassCanada/
|
|
17
|
+
related:
|
|
18
|
+
- ../profile.md
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Summary
|
|
22
|
+
Imports Grand & Toy (G&T) Advance Shipping Notices for Compass Canada. A 1.0 worker cron reads
|
|
23
|
+
G&T's ASN CSV from a mailbox, posts each shipped line to the 2.0 API as an AdvanceShippingNotice
|
|
24
|
+
(ASN); a Compass interceptor then auto-creates the ItemFulfillment chain, and the customer gets
|
|
25
|
+
an in-transit email in English or French. It mirrors the Compass USA ODP / Strategic-Systems ASN
|
|
26
|
+
flow, adapted for Canadian carriers and bilingual email.
|
|
27
|
+
|
|
28
|
+
## Key files / entry points
|
|
29
|
+
- `worker/crons/toga2/compasscanada/workflow/4_import_grand_and_toy_advance_shipping_notices.php`
|
|
30
|
+
— the scheduled cron (1.0 worker tier). Reads mailbox `compasscanada.status@togatech.com`
|
|
31
|
+
(OAuth2 creds in config `[compasscanada]`), parses the 24-column CSV, posts to api2
|
|
32
|
+
`/advance-shipping-notices`. Scheduled in `worker/schedules/cron.worker.sync.json` (every 4h).
|
|
33
|
+
- `_underscore/Model/Compass/AdvanceShippingNotice.php` — `postPost` interceptor that builds the
|
|
34
|
+
ItemFulfillment chain on each ASN POST. Compass Canada inherits it via the empty
|
|
35
|
+
`_underscore/Model/Compass/Canada/AdvanceShippingNotice.php`.
|
|
36
|
+
- `worker/crons/toga2/compasscanada/workflow/import_grand_and_toy_asn_from_file.php` — one-time
|
|
37
|
+
backfill variant: reads a CSV from disk (no mailbox/OAuth), creates ASN data only, sends NO
|
|
38
|
+
user emails/notifications, and stamps `c_dtInTransitEmailSent = NOW()`.
|
|
39
|
+
|
|
40
|
+
## How it works
|
|
41
|
+
1. Cron gets an O365 OAuth2 token (creds from `App_Registry::get('config')['compasscanada']`),
|
|
42
|
+
opens the INBOX.
|
|
43
|
+
2. Per attachment: decode CSV, gate on exactly 24 columns (otherwise email the team the file +
|
|
44
|
+
skip).
|
|
45
|
+
3. Per row: skip electronic-delivery carriers (`Digital` / `E-delivered` / `E-verified`);
|
|
46
|
+
validate PO / part / tracking; look up SO + contact user + CC addresses; resolve carrier →
|
|
47
|
+
Ground shipping method; upsert `TrackingNumbers`; resolve the item by
|
|
48
|
+
`VendorItems.vendorPartNumber`; find-or-create a `Units` row per serial.
|
|
49
|
+
4. POST `/advance-shipping-notices` with the tracking number nested at header + item + unit
|
|
50
|
+
level (so the interceptor sees it during the POST).
|
|
51
|
+
5. The Compass ASN `postPost` interceptor (when enabled) creates the `ItemFulfillment` (one per
|
|
52
|
+
SO number, reused if it exists), `ItemFulfillmentItems`, `ItemFulfillmentItemUnits`, and the
|
|
53
|
+
IF/IFI/IFIU `_TrackingNumbers` bridges.
|
|
54
|
+
6. Only when a tracking number is newly inserted: write Notifications (1.0 `db_store` + 2.0),
|
|
55
|
+
resolve the user's language, send the EN/FR in-transit email via POST
|
|
56
|
+
`/email-templates/sendEmail`, then stamp `c_dtInTransitEmailSent = NOW()`.
|
|
57
|
+
|
|
58
|
+
## Data model
|
|
59
|
+
- ASN: `AdvanceShippingNotices` / `…Items` / `…ItemUnits` + their `…_TrackingNumbers` bridges.
|
|
60
|
+
- IF: `ItemFulfillments` / `…Items` / `…ItemUnits` + their `…_TrackingNumbers` bridges.
|
|
61
|
+
- Vendor: `App_Client_CompassCanada::UUID_VENDOR__GRAND_TOY`.
|
|
62
|
+
- Carriers + methods: `ShippingCarriers` Precision / Purolator / ATSL / Nationex, each with its
|
|
63
|
+
own Ground `ShippingMethods` row (added 2026-06-18 via dbchanges2; tracking-URL prefixes +
|
|
64
|
+
carrier logos set on the carrier).
|
|
65
|
+
- Language: `UserGlobalSettings.settingId = 2`, values `en` / `fr-CA`. In-transit `EmailTemplates`
|
|
66
|
+
uuids — EN `26d2cb67-bdc5-4973-9e39-160c89b0af56`, FR `fb8be211-7c07-4939-9682-08b6c3245f66`.
|
|
67
|
+
- Interceptor wiring: `Core.RecordScripts` + `Core.ApiPayloadInterceptors`, `recordId 55`
|
|
68
|
+
(AdvanceShippingNotice). The `sendEmail` POST record script is `Core.RecordScripts recordId 202`.
|
|
69
|
+
|
|
70
|
+
## Client variations
|
|
71
|
+
Compass-Canada-specific; parallels Compass USA's ODP / Strategic-Systems ASN import. Canada sends
|
|
72
|
+
a bilingual EN/FR in-transit email (USA is English only) and uses Canadian carriers.
|
|
73
|
+
|
|
74
|
+
## Gotchas / known issues
|
|
75
|
+
- **CSV "Part Number" is the VENDOR part number (`VendorItems.vendorPartNumber`), NOT
|
|
76
|
+
`Items.partNumber`.** Resolve the item through `VendorItems`. (e.g. vendor `IMFP3260` →
|
|
77
|
+
`Items.partNumber` `C2CY5UC#ABA`.)
|
|
78
|
+
- **G&T's ASN file inconsistently drops the `IM` prefix** (`FP3260` vs `IMFP3260`) on some lines
|
|
79
|
+
→ item-not-found → those lines are skipped and reported in the import-report email. This is a
|
|
80
|
+
G&T-side export issue; toga transmits the correct `IMFP…` to G&T as the cXML `SupplierPartID`
|
|
81
|
+
(see `2_transmit_mits_purchase_orders_to_vendors.php`), so it is NOT a MITS bug.
|
|
82
|
+
- **The ASN→IF interceptor must be ENABLED per client.** `Core.ApiPayloadInterceptors` for
|
|
83
|
+
`recordId 55`, `prePostProcessing=POST`, `httpMethod=POST` must be `isActive=1` (and the client
|
|
84
|
+
`AclRecordScripts` must grant the caller's roles). It was OFF for Compass Canada; enabling it is
|
|
85
|
+
required or ASNs post but the IF/IFI/IFIU chain never builds.
|
|
86
|
+
- **Tracking must be nested in the ASN POST payload** (header/item/unit), not linked via SQL
|
|
87
|
+
after the POST — the interceptor runs during the POST, so post-POST links are invisible to it.
|
|
88
|
+
- **`/email-templates/sendEmail` must be POST** (not GET) so a large `orderItems` HTML payload
|
|
89
|
+
does not hit the URL-length limit (HTTP 414). POST requires the `sendEmail` record script
|
|
90
|
+
registered for the POST method (`Core.RecordScripts`), else the engine returns `EV-8`.
|
|
91
|
+
- Each CSV line creates one ASN; the interceptor dedups to **one ItemFulfillment per SO**.
|
|
92
|
+
- A new carrier needs its **own** Ground `ShippingMethod`, or the TrackingNumber ends up with the
|
|
93
|
+
right carrier but another carrier's Ground method id.
|
|
94
|
+
- `App_Database::fetchOne()` (1.0) throws on a 0-row result — guard item lookups with `numRows()`
|
|
95
|
+
before `fetchOne()`.
|
|
96
|
+
- The cron reads OAuth2 creds from config `[compasscanada]`; the updated `config.<env>.ini` must
|
|
97
|
+
be deployed with the code or the token request fails.
|
|
98
|
+
|
|
99
|
+
## Change history
|
|
100
|
+
- 2026-06-19 — Built the G&T ASN import cron + one-time backfill script; matched items by
|
|
101
|
+
`VendorItems.vendorPartNumber`; added Canadian carriers + per-carrier Ground methods; EN/FR
|
|
102
|
+
in-transit email via POST; enabled the Compass ASN→IF interceptor for Compass Canada. (bala)
|
|
103
|
+
|
|
104
|
+
## Related docs
|
|
105
|
+
- [Compass Canada profile](../profile.md)
|
|
@@ -12,7 +12,7 @@ project: _Underscore
|
|
|
12
12
|
client: compass-canada
|
|
13
13
|
type: profile
|
|
14
14
|
status: active
|
|
15
|
-
updated: 2026-06-
|
|
15
|
+
updated: 2026-06-19
|
|
16
16
|
owners: [jcardinal, bala]
|
|
17
17
|
files: []
|
|
18
18
|
related:
|
|
@@ -31,10 +31,17 @@ to but distinct from Compass USA. Like Compass USA it spans the **2.0** commerce
|
|
|
31
31
|
- **1.0:** worker crons under `worker/crons/toga2/compasscanada/`.
|
|
32
32
|
|
|
33
33
|
## Vendors & integrations
|
|
34
|
-
-
|
|
34
|
+
- **Grand & Toy (G&T)** — primary hardware vendor. SOs flow toga → MITS → PO to G&T; G&T sends
|
|
35
|
+
back ASNs. ASN ingestion (email CSV + the auto-created ItemFulfillment chain + bilingual
|
|
36
|
+
in-transit email) is documented in [Grand & Toy ASN Import](features/grand-and-toy-asn-import.md).
|
|
37
|
+
Vendor uuid: `App_Client_CompassCanada::UUID_VENDOR__GRAND_TOY`. Canadian carriers in use:
|
|
38
|
+
UPS, FedEx, Purolator, Precision, Nationex, ATSL (each with a Ground `ShippingMethod`).
|
|
39
|
+
- Worker crons for the G&T flow live under `worker/crons/toga2/compasscanada/workflow/`
|
|
40
|
+
(`1_…` transmit SOs to MITS, `2_…` transmit POs to vendors, `3_…` status from G&T cXML,
|
|
41
|
+
`4_…` import G&T ASNs).
|
|
35
42
|
|
|
36
43
|
## Notes
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
- Customer language preference: `UserGlobalSettings.settingId = 2` (`en` / `fr-CA`); customer-
|
|
45
|
+
facing emails are sent in EN or FR accordingly.
|
|
46
|
+
- The 2026-06-08 ASN → ItemFulfillment work was for **Compass USA**, not Compass Canada.
|
|
40
47
|
- Related: [Compass USA](../compass-usa/profile.md).
|
|
@@ -6,8 +6,8 @@ project: TOGA Technology Website
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-06-
|
|
10
|
-
owners: ["ajean"]
|
|
9
|
+
updated: 2026-06-19
|
|
10
|
+
owners: ["ajean", "jcardinal"]
|
|
11
11
|
files:
|
|
12
12
|
- togatech/vite.config.ts
|
|
13
13
|
- togatech/scripts/prerender.mjs
|
|
@@ -24,7 +24,7 @@ related: []
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
26
|
## Summary
|
|
27
|
-
Makes togatech.com visible and citable to search engines **and** AI answer engines (ChatGPT/Perplexity/Claude search, Google AI Overviews). The site is a CSR-only Vite/React SPA, so non-JS crawlers saw an empty `<div id="root">`. This feature fixes a production de-indexing bug and adds **build-time prerendering** so every static route ships real HTML, plus single-source per-page meta and JSON-LD structured data. Shipped on branches `fix-seo-deindex-emergency` (PR #29) and `feature-seo-aeo-prerender` (PR #30)
|
|
27
|
+
Makes togatech.com visible and citable to search engines **and** AI answer engines (ChatGPT/Perplexity/Claude search, Google AI Overviews). The site is a CSR-only Vite/React SPA, so non-JS crawlers saw an empty `<div id="root">`. This feature fixes a production de-indexing bug and adds **build-time prerendering** so every static route ships real HTML, plus single-source per-page meta and JSON-LD structured data. Shipped on branches `fix-seo-deindex-emergency` (PR #29) and `feature-seo-aeo-prerender` (PR #30); **merged into `_production` on 2026-06-19** (Contact page conflict resolved — see gotchas).
|
|
28
28
|
|
|
29
29
|
## Key files / entry points
|
|
30
30
|
- `vite.config.ts` — `robotsPlugin()` now gates on **Vite `mode`** (was `NODE_ENV && VITE_ENV`).
|
|
@@ -35,7 +35,7 @@ Makes togatech.com visible and citable to search engines **and** AI answer engin
|
|
|
35
35
|
|
|
36
36
|
## How it works
|
|
37
37
|
1. **robots:** `robotsPlugin` copies `robots.prod.txt` only when `mode === "production"`; beta/gamma/dev get `robots.dev.txt` (`Disallow: /`). `robots.prod.txt` carries an explicit AI-bot allow-list (GPTBot, ClaudeBot, PerplexityBot, …) + `https://` sitemap.
|
|
38
|
-
2. **prerender:** `npm run build` = `tsc && vite build && node scripts/prerender.mjs
|
|
38
|
+
2. **prerender:** `npm run build` = `tsc && vite build && npx puppeteer browsers install chrome && node scripts/prerender.mjs` (the Chrome-install step was added 2026-06-19 — see gotchas). The script serves `dist/` (reading the original shell once, serving it for all nav routes), snapshots each route in headless Chrome, and writes `dist/<route>/index.html`. Runs in a real browser, so **no SSR/window guards needed**.
|
|
39
39
|
3. **meta:** each page renders `<Seo {...FIELDS.meta} />` — title/description/keywords/canonical/OG/Twitter from one place per page; canonical/OG URLs derived from one `SITE_URL`. `<JsonLd>` (Helmet `<script type="application/ld+json">`) is baked into the snapshot.
|
|
40
40
|
4. **structured data:** Organization + WebSite site-wide (AppLayout), per-page BreadcrumbList (Seo), platform SoftwareApplication (OurPlatform), LocalBusiness×5 (from Contact locations), Person (from About team) — all **derived from existing FIELDS** (single source).
|
|
41
41
|
|
|
@@ -48,7 +48,10 @@ None — uniform.
|
|
|
48
48
|
## Gotchas / known issues
|
|
49
49
|
- **De-indexing bug (root cause):** `robotsPlugin` required `NODE_ENV && VITE_ENV==="production"`, but build scripts set neither → every build shipped `robots.dev.txt` (`Disallow: /`). **Do NOT gate robots on `NODE_ENV`** — `vite build` sets it to `production` for *every* mode, which would expose beta/gamma. Gate on Vite `mode`.
|
|
50
50
|
- **`.npmrc` has `ignore-scripts=true`** → the `postbuild` lifecycle hook never fires. Prerender is therefore chained directly in the `build` script, not a `postbuild` hook.
|
|
51
|
-
- **Prerender tooling:** `vite-react-ssg` supports React Router **6 only** (project is RR 7.9); `react-snap` is stale (2022) and won't launch on Node 24. Hence a custom Puppeteer snapshot.
|
|
51
|
+
- **Prerender tooling:** `vite-react-ssg` supports React Router **6 only** (project is RR 7.9); `react-snap` is stale (2022) and won't launch on Node 24. Hence a custom Puppeteer snapshot.
|
|
52
|
+
- **🔴 Chrome must be installed in the build (now wired in):** Amplify/CodeBuild's `npm ci` does **not** download a browser, so `puppeteer.launch()` fails with `Could not find Chrome (ver. …)` at `/root/.cache/puppeteer`. Fixed 2026-06-19 by adding `npx puppeteer browsers install chrome` to the `build` script immediately before `node scripts/prerender.mjs` (same default cache `launch()` resolves from). puppeteer 25 also requires **Node ≥ 22.12** — set the Amplify image accordingly. (The step re-downloads ~150 MB per build unless `/root/.cache/puppeteer` is cached.)
|
|
53
|
+
- **🔴 `package-lock.json` must be committed:** Amplify preBuild runs `npm ci`, which refuses to run without a committed lockfile (`npm error code EUSAGE`) and will **not** generate one. The lockfile is not gitignored — it was simply never committed; `npm install` once and commit it.
|
|
54
|
+
- **Contact page merge (2026-06-19):** when merging the SEO/AEO feature into `_production`, `ContactPage.tsx` conflicted. Resolution: keep production's reCAPTCHA conditional wrap (`GoogleReCaptchaProvider` mounts only when `VITE_RECAPTCHA_V3_SITE_KEY` is set) **and** the `<Seo>`/`<JsonLd>` components; drop the incoming `<Helmet>` block (superseded by `<Seo>`).
|
|
52
55
|
- **Prerender fail-fast:** a route that never mounts (`#root > *` times out) aborts the build with `process.exit(1)` — otherwise it would snapshot the empty shell (no SEO/JSON-LD) and still exit 0.
|
|
53
56
|
- **🔴 Hosting requirement:** CloudFront/S3 must serve each prerendered `dist/<route>/index.html` for its path; a blanket SPA rewrite to root `index.html` serves the empty shell and defeats the prerender.
|
|
54
57
|
- **og:image dedupe:** static OG/Twitter tags were removed from `index.html` because `<Seo>` emits per-page ones (Helmet appends rather than replacing pre-existing static tags → duplicates otherwise).
|
|
@@ -56,6 +59,7 @@ None — uniform.
|
|
|
56
59
|
- **Build size:** JS bundle is ~14.8 MB (4.9 MB gzip) — a real CWV/LCP risk; code-splitting is a separate follow-up.
|
|
57
60
|
|
|
58
61
|
## Change history
|
|
62
|
+
- 2026-06-19 — Merged SEO/AEO into `_production` (resolved ContactPage conflict: reCAPTCHA + Seo/JsonLd, dropped Helmet). Fixed Amplify build: committed `package-lock.json` (npm ci EUSAGE) and added `npx puppeteer browsers install chrome` to the build before prerender. (jcardinal)
|
|
59
63
|
- 2026-06-18 — Initial SEO/AEO/GEO implementation: robots mode-gate + AI allow-list + sitemap/llms; Puppeteer prerender (fail-fast); shared `<Seo>` single-source meta + canonical; JSON-LD (Organization/WebSite/Breadcrumb/SoftwareApplication/LocalBusiness×5/Person×12). PRs #29 + #30, pending merge. (ajean)
|
|
60
64
|
|
|
61
65
|
## Related docs
|
package/package.json
CHANGED