@vtex/faststore-plugin-buyer-portal 1.3.83 → 1.3.85

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.
@@ -0,0 +1,154 @@
1
+ ---
2
+ name: create-page
3
+ description: >
4
+ Scaffolds a new page in the faststore-plugin-buyer-portal following the
5
+ project's 4-layer architecture (types → loader → component → export).
6
+ Use when the user says "create a page", "add a new page", "cria a página",
7
+ "adiciona a página", or runs /create-page.
8
+ ---
9
+
10
+ # Create Page
11
+
12
+ Scaffold a new page in the buyer-portal plugin by adapting an existing canonical
13
+ example. Do NOT copy blindly — read the canonical, understand each layer, then
14
+ adapt it to the new context.
15
+
16
+ ## Step 1: Gather Input
17
+
18
+ Determine (ask the user if not clear from context):
19
+
20
+ - **Page name** — kebab-case. Example: `cost-centers` → file `src/pages/cost-centers.tsx`
21
+ - **Feature name** — the domain folder under `src/features/`. Usually the same as the page name.
22
+ - **Page type** — one of:
23
+ - `list` — listing with search and pagination (e.g. users, org-units, addresses)
24
+ - `detail` — single-item detail view, receives an ID in the query (e.g. user-details, address-details)
25
+ - `redirect` — simple redirect or entry point (e.g. home)
26
+
27
+ ## Step 2: Check Whether the Feature Exists
28
+
29
+ Run from the project root:
30
+
31
+ ```bash
32
+ ls src/features/<feature-name>/ 2>/dev/null && echo "EXISTS" || echo "NEW"
33
+ ```
34
+
35
+ - **EXISTS** → go to Step 4a (create page + layout only)
36
+ - **NEW** → go to Step 4b (scaffold full feature structure)
37
+
38
+ ## Step 3: Read the Canonical Example
39
+
40
+ Before creating any file, read the canonical that matches the page type:
41
+
42
+ | Type | Canonical page | Canonical layout |
43
+ |------|---------------|-----------------|
44
+ | `list` | `src/pages/users.tsx` | `src/features/users/layouts/UsersLayout/UsersLayout.tsx` |
45
+ | `detail` | `src/pages/user-details.tsx` | `src/features/users/layouts/UserDetailsLayout/UserDetailsLayout.tsx` |
46
+ | `redirect` | `src/pages/home.tsx` | — |
47
+
48
+ Read both files completely. Pay particular attention to the layout file's import structure and the props it receives. Understand the four layers:
49
+
50
+ 1. **Type definitions** — `<Name>PageQuery` (URL params) and `<Name>PageData` (loader output)
51
+ 2. **Loader** — `withAuthLoader` enforcing auth + `withLoaderErrorBoundary` for error propagation
52
+ 3. **Component** — checks `hasError`; renders `ErrorTabsLayout` on error, feature layout otherwise
53
+ 4. **Export** — `withProviders(withErrorBoundary(Component, { tags: { ... } }))`
54
+
55
+ > **Note for `redirect` pages:** The `redirect` canonical (`home.tsx`) does not follow layers 1–3. Its component simply calls a router method and returns `null`. Read `home.tsx` directly and adapt it as-is — do not apply the type/loader/hasError pattern to redirect pages.
56
+
57
+ ## Step 4a: Feature EXISTS — Create Page + Layout
58
+
59
+ Create these files, adapting from the canonical (rename types, adjust query params, fix imports):
60
+
61
+ **`src/pages/<page-name>.tsx`**
62
+ Adapt the canonical page file. Replace every occurrence of the canonical feature name
63
+ with the new feature name (types, imports, service calls, layout references). Keep the
64
+ four-layer structure intact.
65
+
66
+ **`src/features/<feature-name>/layouts/<FeatureName>Layout/<FeatureName>Layout.tsx`**
67
+ Minimal layout component. It must:
68
+ - Accept `data` typed as `<Name>PageData['data']` (not the full page data)
69
+ - Return a placeholder `<div>` or a minimal FastStore UI shell — no business logic yet
70
+
71
+ **`src/features/<feature-name>/layouts/<FeatureName>Layout/<feature-name>-layout.scss`**
72
+ Empty SCSS file. Just create it so the import in the layout resolves.
73
+
74
+ **`src/features/<feature-name>/layouts/index.ts`**
75
+ If this file does not exist, create it:
76
+ ```typescript
77
+ export { <FeatureName>Layout } from './<FeatureName>Layout/<FeatureName>Layout'
78
+ ```
79
+ If it already exists, add the export line for the new layout.
80
+
81
+ ## Step 4b: Feature NEW — Scaffold Full Structure
82
+
83
+ Create all files from Step 4a, plus:
84
+
85
+ **`src/features/<feature-name>/types/index.ts`**
86
+ ```typescript
87
+ // Replace with real domain types as the feature is implemented
88
+ export type <FeatureName>Data = Record<string, unknown>
89
+ ```
90
+
91
+ **`src/features/<feature-name>/services/.gitkeep`**
92
+ Empty file. Services will be added when data fetching is implemented.
93
+
94
+ **`src/features/<feature-name>/hooks/.gitkeep`**
95
+ Empty file. Hooks will be added as needed.
96
+
97
+ **`src/features/<feature-name>/layouts/index.ts`**
98
+ If this file does not exist, create it:
99
+ ```typescript
100
+ export { <FeatureName>Layout } from './<FeatureName>Layout/<FeatureName>Layout'
101
+ ```
102
+ If it already exists, add the export line for the new layout.
103
+
104
+ ## Step 5: Register the Route
105
+
106
+ **Ask the user** for the route path and URL params if not already provided.
107
+
108
+ **`plugin.config.js`** — add an entry inside the `pages` object:
109
+
110
+ ```js
111
+ "<page-name>": {
112
+ path: "/pvt/organization-account/<your-path>/[param1]/[param2]",
113
+ appLayout: false,
114
+ },
115
+ ```
116
+
117
+ Follow the existing conventions:
118
+ - List pages typically use `/pvt/organization-account/<name>/[orgUnitId]` or `[orgUnitId]/[contractId]`
119
+ - Detail pages typically add the entity ID at the end: `[orgUnitId]/[contractId]/[<entityId>]`
120
+ - All entries must have `appLayout: false`
121
+
122
+ **`src/features/shared/utils/buyerPortalRoutes.ts`** — add a typed helper to the `buyerPortalRoutes` object:
123
+
124
+ ```typescript
125
+ // camelCase name, matching the pattern of existing entries
126
+ <camelCaseName>: (params: { orgUnitId: string; /* add other params */ }) =>
127
+ replaceParams(`${base}/<your-path>/[orgUnitId]/[...]`, params),
128
+ ```
129
+
130
+ Use an arrow function with a typed params object for parameterized routes. Use a plain string (like `b2bAgent`) only for routes with no dynamic segments.
131
+
132
+ ## Step 6: Validate
133
+
134
+ Run:
135
+
136
+ ```bash
137
+ make typecheck
138
+ ```
139
+
140
+ Then verify manually:
141
+
142
+ - [ ] `<Name>PageData` is exported from the page file
143
+ - [ ] `loader` is a named export (`export const loader`)
144
+ - [ ] The default export is `withProviders(withErrorBoundary(<Component>, { tags: { component: '<Name>Page', errorType: '<feature>_error' } }))`
145
+ - [ ] The component checks `hasError` and renders `<ErrorTabsLayout>` on error
146
+ - [ ] The layout receives only `data` (typed as `<Name>PageData['data']`), not the full page object
147
+ - [ ] No broken imports (`make typecheck` must pass with zero errors)
148
+
149
+ ## Step 7: Commit
150
+
151
+ ```bash
152
+ git add src/pages/<page-name>.tsx src/features/<feature-name>/
153
+ git commit -m "feat: add <page-name> page"
154
+ ```
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "create-page",
3
+ "description": "Scaffolds a new page in the faststore-plugin-buyer-portal following the project's 4-layer architecture (types → loader → component → export). Adaptive: creates full feature structure for new features, or just page + layout for existing ones. Reads canonical examples from the codebase instead of using hardcoded templates.",
4
+ "version": "1.0.0",
5
+ "triggers": [
6
+ "/create-page",
7
+ "create a page",
8
+ "add a new page",
9
+ "add a page",
10
+ "nova página",
11
+ "cria a página",
12
+ "adiciona a página"
13
+ ]
14
+ }
package/.editorconfig ADDED
@@ -0,0 +1,15 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 2
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
10
+
11
+ [*.md]
12
+ trim_trailing_whitespace = false
13
+
14
+ [Makefile]
15
+ indent_style = tab
package/.env.example ADDED
@@ -0,0 +1,3 @@
1
+ # Optional — Node environment. Affects error detail visibility in dev tools.
2
+ # Valid values: development | production | test
3
+ NODE_ENV=development
@@ -1,4 +1,4 @@
1
- name: Lint
1
+ name: Lint and Test
2
2
 
3
3
  on:
4
4
  pull_request:
@@ -9,30 +9,32 @@ on:
9
9
  jobs:
10
10
  lint:
11
11
  runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - uses: actions/setup-node@v4
16
+ with:
17
+ node-version: "20.x"
18
+ cache: "yarn"
12
19
 
13
- strategy:
14
- matrix:
15
- node-version: [20.x]
20
+ - name: Install dependencies
21
+ run: make install
22
+
23
+ - name: Lint
24
+ run: make lint
16
25
 
26
+ test:
27
+ runs-on: ubuntu-latest
17
28
  steps:
18
- - name: Checkout code
19
- uses: actions/checkout@v4
29
+ - uses: actions/checkout@v4
20
30
 
21
- - name: Setup Node.js ${{ matrix.node-version }}
22
- uses: actions/setup-node@v4
31
+ - uses: actions/setup-node@v4
23
32
  with:
24
- node-version: ${{ matrix.node-version }}
33
+ node-version: "20.x"
25
34
  cache: "yarn"
26
35
 
27
36
  - name: Install dependencies
28
- run: yarn install --frozen-lockfile
29
-
30
- - name: Run ESLint
31
- run: yarn lint
37
+ run: make install
32
38
 
33
- - name: Check for ESLint errors
34
- run: |
35
- if yarn lint 2>&1 | grep -q "error"; then
36
- echo "ESLint found errors. Please fix them before merging."
37
- exit 1
38
- fi
39
+ - name: Test
40
+ run: make test
@@ -0,0 +1,83 @@
1
+ <!-- SYNC IMPACT REPORT
2
+ Version change: (template) → 1.0.0
3
+ Added sections: Core Principles (I–V), Technical Standards, Development Workflow, Governance
4
+ Removed sections: none (first version)
5
+ Templates updated:
6
+ ✅ .specify/memory/constitution.md — this file
7
+ ✅ .specify/templates/plan-template.md — no constitution-specific references to update
8
+ ✅ .specify/templates/spec-template.md — no constitution-specific references to update
9
+ ✅ .specify/templates/tasks-template.md — no constitution-specific references to update
10
+ Deferred TODOs: none
11
+ -->
12
+
13
+ # FastStore Plugin Buyer Portal Constitution
14
+
15
+ ## Core Principles
16
+
17
+ ### I. Plugin Encapsulation (NON-NEGOTIABLE)
18
+ All functionality MUST be delivered as a FastStore plugin. Routes MUST be registered in
19
+ `plugin.config.js`. No logic may leak outside the plugin boundary or assume a specific
20
+ host store structure. The plugin must be linkable via `yarn link` and must not break the
21
+ host store's build.
22
+
23
+ ### II. Feature-per-Domain Structure
24
+ Source code is organized under `src/features/<domain>/`. Each domain (org-units, users,
25
+ roles, budgets, buying-policies, credit-cards, contracts, etc.) MUST be self-contained:
26
+ its own components, hooks, services, types, and mocks. Cross-domain dependencies MUST go
27
+ through `src/features/shared/`. No domain may import directly from another domain.
28
+
29
+ ### III. Type Safety (NON-NEGOTIABLE)
30
+ TypeScript strict mode is always on. Code MUST compile with zero errors under
31
+ `tsc --noEmit`. Use of `any` MUST be explicitly justified with a comment. Pre-commit hooks
32
+ enforce lint and type-safe imports via Husky + lint-staged. All new code MUST pass
33
+ `make lint` and `make typecheck` before merge.
34
+
35
+ ### IV. Test Coverage
36
+ Unit tests (Vitest) MUST cover core domain logic — pure functions, transformations, and
37
+ shared utilities. E2E tests (Cypress) cover critical buyer portal flows. `make test` MUST
38
+ exit 0 in CI. New features MUST ship with at least one unit test; new API integrations
39
+ MUST include an integration test for the happy path.
40
+
41
+ ### V. Spec-Driven Development
42
+ All non-trivial features MUST start with a spec before any implementation begins. Use
43
+ `/speckit-specify` to draft the spec, `/speckit-plan` for the implementation plan, and
44
+ `/speckit-tasks` for task breakdown. Specs live in `specs/` and MUST be approved before
45
+ the first commit of implementation code.
46
+
47
+ ## Technical Standards
48
+
49
+ > Principles, feature flags flow, Makefile commands, and key files are documented in
50
+ > [`docs/conventions.md`](../../docs/conventions.md).
51
+
52
+ - **Package manager**: Yarn (enforced via `packageManager` field — do not use npm or pnpm)
53
+ - **Node target**: ES2022, NodeNext module resolution
54
+ - **Release toolchain**: `release-it` with Keep a Changelog format; version bumps update
55
+ both `package.json` and `src/features/shared/utils/constants.ts`
56
+ - **Import order**: builtin → external → internal (enforced by eslint-plugin-import).
57
+ React imports MUST precede other externals.
58
+
59
+ ## Development Workflow
60
+
61
+ 1. Create a spec with `/speckit-specify` for any feature or bugfix larger than a one-liner.
62
+ 2. Get spec approved before writing implementation code.
63
+ 3. Run `make install` on a fresh clone to set up the environment.
64
+ 4. Run `make check` (lint + typecheck + test) before opening a PR.
65
+ 5. All PRs target `main`. The `golden-path/` prefix is reserved for SDLC infrastructure
66
+ branches.
67
+ 6. Changelog MUST be updated in the `[Unreleased]` section for every PR that ships
68
+ user-visible changes.
69
+ 7. Releases are cut via `yarn release` (stable) or `yarn release:beta`. Never bump the
70
+ version manually.
71
+
72
+ ## Governance
73
+
74
+ This constitution supersedes all other informal practices. Amendments require:
75
+ 1. A PR modifying this file with the version bumped per semantic rules (MAJOR for
76
+ principle removals/redefinitions, MINOR for additions, PATCH for clarifications).
77
+ 2. Review and approval by at least one team member.
78
+ 3. A migration note if existing code violates the new principle.
79
+
80
+ All PRs MUST be verified for compliance with the principles above before merge. Complexity
81
+ that conflicts with these principles MUST be justified in the PR description.
82
+
83
+ **Version**: 1.0.0 | **Ratified**: 2026-05-11 | **Last Amended**: 2026-05-11
package/AGENTS.md ADDED
@@ -0,0 +1,84 @@
1
+ # AGENTS.md — FastStore Plugin Buyer Portal
2
+
3
+ This file provides guidance for AI agents working in this repository.
4
+
5
+ ## What this project is
6
+
7
+ `@vtex/faststore-plugin-buyer-portal` is a **FastStore plugin** that delivers a B2B buyer
8
+ organization portal (also called "Organization Account"). It is consumed by FastStore
9
+ storefronts via `yarn link` and exposes pages for managing org units, users, roles,
10
+ budgets, buying policies, credit cards, contracts, and more.
11
+
12
+ It is **not** a standalone application — it is a plugin. There is no `yarn dev` in this
13
+ repo. Testing UI changes requires linking it to a host store (see [docs/README.md](docs/README.md)).
14
+
15
+ ## Orientation
16
+
17
+ ```
18
+ src/
19
+ features/
20
+ <domain>/ # self-contained per domain (components, hooks, services, types)
21
+ shared/ # cross-domain utilities, constants, routes
22
+ pages/ # one file per buyer portal route
23
+ apis/ # custom API routes
24
+ docs/ # runbook, feature flags guide, troubleshooting
25
+ .specify/ # spec-kit config, constitution, templates
26
+ .agents/skills/ # SDD Lite agent skills
27
+ .claude/skills/ # spec-kit Claude skills
28
+ ```
29
+
30
+ Key files:
31
+ - `plugin.config.js` — route registration (required for new pages)
32
+ - `src/features/shared/utils/constants.ts` — shared constants including plugin version
33
+ - `src/features/shared/utils/buyerPortalRoutes.ts` — all route definitions
34
+ - `.specify/memory/constitution.md` — project principles (read before making changes)
35
+
36
+ ## How to set up
37
+
38
+ ```bash
39
+ make install # install dependencies
40
+ make check # lint + typecheck + test (must pass before any PR)
41
+ make setup-tools # install spec-kit v0.6.0 (first time only, requires uv)
42
+ ```
43
+
44
+ For UI development, see [docs/README.md](docs/README.md) — requires linking to
45
+ `vtex-sites/b2bfaststoredev.store`.
46
+
47
+ ## Development rules
48
+
49
+ See [docs/conventions.md](docs/conventions.md) for the canonical principles (plugin boundary, feature-per-domain, type safety, tests, spec-first), feature flags flow, Makefile reference, and key files.
50
+
51
+ ## How to add a new page
52
+
53
+ > Use `/create-page` to scaffold steps 1–3 automatically (it will ask you for the route path). Step 4 must always be done manually.
54
+
55
+ 1. Create `src/pages/<page-name>.tsx`
56
+ 2. Create `src/features/<domain>/` with components, hooks, services, types
57
+ 3. Register the route in `plugin.config.js`
58
+ 4. Add the route constant to `src/features/shared/utils/buyerPortalRoutes.ts`
59
+
60
+ ## Feature flags
61
+
62
+ See [docs/conventions.md](docs/conventions.md#feature-flags).
63
+
64
+ ## Skills available
65
+
66
+ | Skill | Purpose |
67
+ |-------|---------|
68
+ | `/speckit-specify` | Draft a spec for a new feature |
69
+ | `/speckit-plan` | Generate an implementation plan from a spec |
70
+ | `/speckit-tasks` | Break a plan into actionable tasks |
71
+ | `/speckit-implement` | Execute an approved spec |
72
+ | `/speckit-constitution` | Update the project constitution |
73
+ | `/specification` | SDD Lite — write a spec document |
74
+ | `/implementing` | SDD Lite — implement an approved spec |
75
+ | `/create-page` | Scaffold a new page (adaptive: full feature or page+layout only) |
76
+
77
+ ## CI
78
+
79
+ | Workflow | Trigger | What it runs |
80
+ |----------|---------|--------------|
81
+ | `lint.yml` | PR + push to main | `make lint`, `make typecheck`, `make test` |
82
+ | `ci.yml` | PR labeled `run-tests` | Cypress E2E against `b2bfaststoredev.store` |
83
+ | `changelog.yml` | PR | Validates changelog entry |
84
+ | `release.yaml` | Manual | Publishes to npm |
package/CHANGELOG.md CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.3.85] - 2026-05-13
11
+
12
+ ### Added
13
+
14
+ - VTEX Golden Path — AI-friendly workspace setup: `.editorconfig`, `.env.example`, Vitest test framework with unit tests, `Makefile` with canonical targets (`install`, `test`, `coverage`, `lint`, `typecheck`, `check`, `clean`), `setup-tools` target for spec-kit v0.6.0, SDD Lite skills (`specification`, `implementing`, `sdlc-ai-ready-repo`, `sdlc-golden-path`)
15
+ - Updated CI workflow to use Makefile targets and added unit test job
16
+
17
+ ## [1.3.84] - 2026-05-07
18
+
19
+ ### Fixed
20
+
21
+ - Align payment methods scope-config requests with the new `payment-groups` BFF by changing `SCOPE_KEYS.PAYMENT_SYSTEMS` value from `paymentSystemIds` to `paymentGroups`. The sync vs custom mode toggle and read on the payment methods page now hit `/scopes/configs?scopeName=paymentGroups`
22
+
10
23
  ## [1.3.83] - 2026-05-05
11
24
 
12
25
  ### Added
@@ -615,7 +628,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
615
628
  - Add CHANGELOG file
616
629
  - Add README file
617
630
 
618
- [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.83...HEAD
631
+ [unreleased]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/1.3.85...HEAD
619
632
  [1.3.55]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.54...v1.3.55
620
633
  [1.3.54]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.53...v1.3.54
621
634
  [1.3.53]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.52...v1.3.53
@@ -683,6 +696,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
683
696
  [1.3.65]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.64...v1.3.65
684
697
  [1.3.64]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.64
685
698
  [1.3.69]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.69
699
+ [1.3.84]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.83...v1.3.84
686
700
  [1.3.83]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.82...v1.3.83
687
701
  [1.3.82]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.81...v1.3.82
688
702
  [1.3.81]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.80...v1.3.81
@@ -697,3 +711,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
697
711
  [1.3.72]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.71...v1.3.72
698
712
  [1.3.71]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.70...v1.3.71
699
713
  [1.3.70]: https://github.com/vtex/faststore-plugin-buyer-portal/compare/v1.3.69...v1.3.70
714
+
715
+ [1.3.85]: https://github.com/vtex/faststore-plugin-buyer-portal/releases/tag/1.3.85