Skip to content

Commit 0b234e1

Browse files
committed
Merge remote-tracking branch 'origin/main' into code-apply-patch
# Conflicts: # package-lock.json # packages/spacecat-shared-cloud-manager-client/src/index.js
2 parents 5058614 + 8b6f098 commit 0b234e1

File tree

214 files changed

+34437
-12062
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

214 files changed

+34437
-12062
lines changed

.github/CODEOWNERS

Lines changed: 0 additions & 2 deletions
This file was deleted.

.github/workflows/main.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
- name: Set up Node.js 22 (temporary - for bootstrap)
6262
uses: actions/setup-node@v6
6363
with:
64-
node-version: '22.21.1'
64+
node-version: '22.22.1'
6565

6666
- name: Update NPM
6767
run: npm install -g npm@10.9.4

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
24.11.1
1+
24.14.0
22

CLAUDE.md

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Commands
6+
7+
```bash
8+
# Install all dependencies (root + all packages)
9+
npm install
10+
11+
# Run all tests across all packages
12+
npm test
13+
14+
# Run tests for a single package
15+
npm test -w packages/spacecat-shared-utils
16+
17+
# Run integration tests (data-access only, requires Docker)
18+
npm run test:it -w packages/spacecat-shared-data-access
19+
20+
# Lint all packages
21+
npm run lint
22+
23+
# Lint a single package
24+
npm run lint -w packages/spacecat-shared-utils
25+
26+
# Generate API docs
27+
npm run docs
28+
29+
# Dry-run semantic release (on non-main branches)
30+
npm run semantic-release-dry
31+
32+
# Clean node_modules and lock file
33+
npm run clean
34+
```
35+
36+
Node >=22 <25 is required (see `.nvmrc` for exact version). The project is pure ESM (`"type": "module"`).
37+
38+
Coverage enforcement: **100% lines/statements, 97% branches** per package (see each package's `.nycrc.json`).
39+
40+
---
41+
42+
## Architecture Overview
43+
44+
This is the **foundation library layer** for all SpaceCat Node.js services. It's an npm workspaces monorepo (no lerna/nx) containing 22 packages that provide data access, API clients, utilities, and auth used by `spacecat-api-service`, `spacecat-audit-worker`, `spacecat-import-worker`, and other platform services.
45+
46+
### Monorepo Structure
47+
48+
```
49+
spacecat-shared/
50+
├── packages/ # 22 npm workspace packages
51+
│ ├── spacecat-shared-data-access/ # Core data layer (PostgREST + Aurora PostgreSQL)
52+
│ ├── spacecat-shared-http-utils/ # HTTP response helpers + auth middleware
53+
│ ├── spacecat-shared-utils/ # General utilities (validation, S3, SQS, helpers)
54+
│ ├── spacecat-shared-rum-api-client/ # RUM Bundler API client
55+
│ ├── spacecat-shared-vault-secrets/ # HashiCorp Vault secrets (replaces helix-shared-secrets)
56+
│ ├── spacecat-shared-*-client/ # 13+ API clients (ahrefs, google, slack, etc.)
57+
│ ├── spacecat-shared-html-analyzer/ # HTML analysis utilities
58+
│ └── spacecat-shared-example/ # Example/template package
59+
├── docs/ # Generated API docs
60+
├── eslint.config.js # Root ESLint flat config
61+
├── .releaserc.cjs # Root semantic-release config
62+
└── package.json # Monorepo root (private, workspaces: ./packages/*)
63+
```
64+
65+
### Package Catalog
66+
67+
| Category | Packages | Purpose |
68+
|----------|----------|---------|
69+
| **Data layer** | `data-access` | Entity models/collections backed by PostgreSQL via PostgREST |
70+
| **HTTP/Auth** | `http-utils` | HTTP response helpers, auth handlers (ScopedApiKey, LegacyApiKey, IMS) |
71+
| **Utilities** | `utils` | Validation, S3/SQS helpers, schemas, date functions |
72+
| **Secrets** | `vault-secrets` | HashiCorp Vault integration (AppRole auth, KV secrets) |
73+
| **HTML** | `html-analyzer` | HTML analysis and extraction |
74+
| **API clients** | `ahrefs-client`, `athena-client`, `brand-client`, `cloud-manager-client`, `content-client`, `drs-client`, `google-client`, `gpt-client`, `ims-client`, `launchdarkly-client`, `rum-api-client`, `scrape-client`, `slack-client`, `splunk-client`, `tier-client`, `tokowaka-client` | External service integrations |
75+
| **Example** | `example` | Template for creating new packages |
76+
77+
### Package-Level CLAUDE.md Files
78+
79+
Some packages have their own CLAUDE.md with deeper architectural guidance:
80+
81+
- [`packages/spacecat-shared-data-access/CLAUDE.md`](packages/spacecat-shared-data-access/CLAUDE.md) — Entity pattern, SchemaBuilder DSL, PostgREST queries, integration tests
82+
- [`packages/spacecat-shared-vault-secrets/CLAUDE.md`](packages/spacecat-shared-vault-secrets/CLAUDE.md) — Vault pipeline, AppRole auth, E2E validation
83+
- [`packages/spacecat-shared-google-client/docs/CLAUDE.md`](packages/spacecat-shared-google-client/docs/CLAUDE.md) — GSC client, OAuth, environment variables
84+
85+
---
86+
87+
## Key Patterns
88+
89+
### Per-Package File Structure
90+
91+
Each package follows this layout:
92+
93+
```
94+
packages/spacecat-shared-<name>/
95+
├── src/ # Source code
96+
│ └── index.js # Package entry point (barrel exports)
97+
├── test/ # Tests (mirrors src/ structure)
98+
├── package.json # Package metadata, dependencies, scripts
99+
├── .releaserc.cjs # semantic-release config (extends monorepo)
100+
├── .nycrc.json # c8 coverage config
101+
├── README.md
102+
└── CHANGELOG.md # Auto-generated by semantic-release
103+
```
104+
105+
### Entity Pattern (data-access)
106+
107+
The data-access package defines entities with 4 files per entity:
108+
109+
```
110+
src/models/<entity>/
111+
<entity>.schema.js # SchemaBuilder definition (attributes, references, indexes)
112+
<entity>.model.js # Extends BaseModel (business logic, constants)
113+
<entity>.collection.js # Extends BaseCollection (custom queries)
114+
index.js # Re-exports model, collection, schema
115+
```
116+
117+
See [`packages/spacecat-shared-data-access/CLAUDE.md`](packages/spacecat-shared-data-access/CLAUDE.md) for the SchemaBuilder DSL, attribute options, and field mapping details.
118+
119+
### Field Mapping Convention
120+
121+
Models use **camelCase**, the database uses **snake_case**. Mapping is automatic via `postgrest.utils.js`. Override with `postgrestField: 'custom_name'` on individual attributes.
122+
123+
### TypeScript Declarations
124+
125+
Packages provide `.d.ts` files for public APIs — no TypeScript source code. Type declarations live alongside the source files they describe.
126+
127+
### API Client Pattern
128+
129+
API clients typically follow this structure:
130+
131+
```js
132+
export default class FooClient {
133+
constructor(config, log) { /* ... */ }
134+
async someOperation(params) { /* ... */ }
135+
}
136+
137+
// Factory function exported from index.js
138+
export function createFooClient(config, log) {
139+
return new FooClient(config, log);
140+
}
141+
```
142+
143+
---
144+
145+
## Testing
146+
147+
**Framework:** Mocha + Chai + chai-as-promised + sinon + sinon-chai
148+
**Coverage:** c8 (per-package `.nycrc.json`)
149+
**HTTP mocking:** nock
150+
**Reporters:** mocha-multi-reporters (spec + xunit)
151+
152+
### Running Tests
153+
154+
```bash
155+
# All packages
156+
npm test
157+
158+
# Single package
159+
npm test -w packages/spacecat-shared-utils
160+
161+
# Integration tests (data-access only — requires Docker + ECR access)
162+
npm run test:it -w packages/spacecat-shared-data-access
163+
```
164+
165+
### Test Conventions
166+
167+
- Tests live in `test/` (or `test/unit/`) and mirror the `src/` directory structure
168+
- Use `describe`/`it` blocks with `expect` assertions
169+
- sinon stubs for external dependencies; nock for HTTP mocking
170+
- Each test file uses a sandbox: `const sandbox = sinon.createSandbox()` with `afterEach(() => sandbox.restore())`
171+
- Coverage thresholds are enforced per package
172+
173+
### Integration Tests (data-access)
174+
175+
Integration tests require the `mysticat-data-service` Docker image from ECR:
176+
177+
```bash
178+
# ECR login (one-time)
179+
aws ecr get-login-password --profile spacecat-dev --region us-east-1 \
180+
| docker login --username AWS --password-stdin 682033462621.dkr.ecr.us-east-1.amazonaws.com
181+
182+
npm run test:it -w packages/spacecat-shared-data-access
183+
```
184+
185+
---
186+
187+
## Working with the Monorepo
188+
189+
### Inter-Package Dependencies
190+
191+
Some packages depend on others in the monorepo (e.g., `data-access` depends on `utils`). These are declared as regular npm dependencies with the published `@adobe/spacecat-shared-*` package name and version.
192+
193+
### Running Commands for a Single Package
194+
195+
Use the `-w` (workspace) flag:
196+
197+
```bash
198+
npm test -w packages/spacecat-shared-<name>
199+
npm run lint -w packages/spacecat-shared-<name>
200+
```
201+
202+
### Adding a New Package
203+
204+
1. Copy `packages/spacecat-shared-example/` as a starting template
205+
2. Rename the directory to `spacecat-shared-<name>`
206+
3. Update `package.json`: name (`@adobe/spacecat-shared-<name>`), description, dependencies
207+
4. Update `.releaserc.cjs` (inherits from root)
208+
5. Implement source in `src/`, tests in `test/`
209+
6. Ensure 100% coverage with `.nycrc.json` thresholds
210+
7. The root `workspaces: ["./packages/*"]` auto-discovers it
211+
212+
### Adding a New Entity (data-access)
213+
214+
1. Create 4 files in `src/models/<entity>/`: `schema.js`, `model.js`, `collection.js`, `index.js`
215+
2. Register the entity in `src/models/index.js`
216+
3. The corresponding DB migration must be created in [mysticat-data-service](https://github.com/adobe/mysticat-data-service)
217+
4. Add unit tests in `test/unit/models/<entity>/`
218+
219+
### Adding a New Import Type (data-access)
220+
221+
1. Update three locations in `src/models/site/config.js`: `IMPORT_TYPES`, `IMPORT_TYPE_SCHEMAS`, `DEFAULT_IMPORT_CONFIGS`
222+
2. Update three corresponding assertions in `test/unit/models/site/config.test.js`
223+
224+
See [`packages/spacecat-shared-data-access/CLAUDE.md`](packages/spacecat-shared-data-access/CLAUDE.md) for full details including code examples.
225+
226+
---
227+
228+
## Commits and Releases
229+
230+
- **Conventional commits** are required — use `npm run commit` (commitizen) or write them manually
231+
- **Pre-commit hook** (husky + lint-staged) runs ESLint on staged `.js` files
232+
- **semantic-release** with `semantic-release-monorepo` handles per-package versioning
233+
- Release happens automatically on push to `main` — each package is released independently based on commits touching its files
234+
- **Branch:** `main` is the only release branch
235+
236+
### After Publishing
237+
238+
When a new version of a `spacecat-shared-*` package is published, update the dependency version in all consuming repos (`spacecat-api-service`, `spacecat-audit-worker`, `spacecat-import-worker`, etc.).
239+
240+
---
241+
242+
## Linting
243+
244+
- **Config:** `eslint.config.js` (ESLint flat config)
245+
- **Base:** `@adobe/eslint-config-helix` (recommended + source + test presets)
246+
- **Parser:** `@babel/eslint-parser` with ESM + import assertions
247+
- **Test overrides:** `no-console: off`, `func-names: off`
248+
- **Ignored:** `.vscode`, `.idea`, `coverage`, `docs`, `vendor`, `dist`, `.releaserc.cjs`, `test/fixtures`

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ $ npm install @adobe/spacecat-shared-http-utils
1414
$ npm install @adobe/spacecat-shared-utils
1515
```
1616

17-
## Usage
17+
## Usage
1818
See the [API documentation](docs/API.md).
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# CWV Trends Audit — spacecat-shared Changes
2+
3+
## Overview
4+
5+
Adds the `CWV_TRENDS_AUDIT` audit type to `Audit.AUDIT_TYPES` in the `spacecat-shared-data-access` package, enabling the new CWV Trends Audit feature across the SpaceCat ecosystem.
6+
7+
## Change
8+
9+
**File:** `packages/spacecat-shared-data-access/src/models/audit/audit.model.js`
10+
11+
```javascript
12+
static AUDIT_TYPES = {
13+
// ... existing types ...
14+
CWV_TRENDS_AUDIT: 'cwv-trends-audit',
15+
};
16+
```
17+
18+
## Context
19+
20+
The CWV Trends Audit is a weekly audit (`every-sunday`) that:
21+
22+
- Reads 28 days of pre-imported CWV data from S3 (`metrics/cwv-trends/cwv-trends-daily-{date}.json`)
23+
- Classifies URLs as Good / Needs Improvement / Poor using standard CWV thresholds
24+
- Determines device type (mobile/desktop) from site handler configuration
25+
- Creates/updates device-specific opportunities: "Mobile Web Performance Trends Report" or "Desktop Web Performance Trends Report"
26+
- Syncs per-URL suggestions with `CONTENT_UPDATE` type
27+
28+
## Dependent Repositories
29+
30+
| Repository | Dependency | Action Required |
31+
|---|---|---|
32+
| `spacecat-audit-worker` | `@adobe/spacecat-shared-data-access` | Bump version after this package is published |
33+
| `spacecat-api-service` | `@adobe/spacecat-shared-data-access` | Bump version to recognize the new audit type |
34+
35+
## Deployment Order
36+
37+
1. Merge this PR → semantic-release publishes new `@adobe/spacecat-shared-data-access`
38+
2. Bump dependency in `spacecat-audit-worker` and `spacecat-api-service`
39+
3. Register audit: `registerAudit('cwv-trends-audit', false, 'every-sunday', [productCodes])`

0 commit comments

Comments
 (0)