@glidevvr/storage-payload-error-logger-pkg 0.1.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.
- package/README.md +229 -0
- package/dist/chunk-EKIOMBUO.mjs +282 -0
- package/dist/chunk-EKIOMBUO.mjs.map +1 -0
- package/dist/index.d.cts +99 -0
- package/dist/index.d.ts +99 -0
- package/dist/index.js +332 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +37 -0
- package/dist/index.mjs.map +1 -0
- package/dist/payload-endpoint/index.d.cts +96 -0
- package/dist/payload-endpoint/index.d.ts +96 -0
- package/dist/payload-endpoint/index.js +206 -0
- package/dist/payload-endpoint/index.js.map +1 -0
- package/dist/payload-endpoint/index.mjs +179 -0
- package/dist/payload-endpoint/index.mjs.map +1 -0
- package/dist/react/index.d.cts +26 -0
- package/dist/react/index.d.ts +26 -0
- package/dist/react/index.js +302 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +28 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/types-BLz-TUBl.d.cts +198 -0
- package/dist/types-BLz-TUBl.d.ts +198 -0
- package/package.json +62 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
type Severity = "error" | "warning" | "info";
|
|
2
|
+
type Source = "payload" | "theme" | "unit-table" | "reservation-app" | "rental-app" | "login";
|
|
3
|
+
type Repo = "gli-payload-multitenant" | "storage-theme-payload" | "unit-table" | "reservation-app" | "rental-app" | "npm-golocal-cloud-wrapper" | "golocal-cloud-wrapper";
|
|
4
|
+
/**
|
|
5
|
+
* Closed enum of failure-classification codes.
|
|
6
|
+
*
|
|
7
|
+
* Splits into two groups:
|
|
8
|
+
* 1. The 15 SE `errorTag` values shared with `@glidevvr/se-components` —
|
|
9
|
+
* keep these in lockstep with that library.
|
|
10
|
+
* 2. Internal codes for failures that aren't an SE-API call (silent empty
|
|
11
|
+
* results, build/scraper/hook errors, uncaught exceptions, etc.).
|
|
12
|
+
*
|
|
13
|
+
* Adding a new value here is intentional. If the failure mode you're logging
|
|
14
|
+
* doesn't fit any value, either add one to this list or use
|
|
15
|
+
* `"unhandled_exception"` (the deliberate "we don't know" bucket).
|
|
16
|
+
*/
|
|
17
|
+
type Reason = "unit_not_found" | "unit_not_available" | "unit_unavailable" | "facility_not_found" | "invalid_tenant_credentials" | "unauthorized" | "session_expired" | "tenant_not_found" | "reservation_not_found" | "ledger_not_found" | "promotion_not_found" | "payment_failed" | "payment_declined" | "invalid_payment_option" | "validation_error" | "unit_list_empty" | "expected_data_missing" | "cache_stale" | "build_failure" | "hook_error" | "scraper_failure" | "data_integrity" | "unhandled_exception" | "network_timeout";
|
|
18
|
+
interface InitLoggerConfig {
|
|
19
|
+
/** Absolute URL to the Payload endpoint (e.g. https://payloadstorage.golocaldev.com/cms/api/log-error). */
|
|
20
|
+
endpoint: string;
|
|
21
|
+
/** Repo identifier — stamped on every event. */
|
|
22
|
+
repo: Repo;
|
|
23
|
+
/** Build identifier (git SHA / build ID) — stamped on every event. */
|
|
24
|
+
release?: string;
|
|
25
|
+
/** reCAPTCHA v3 site key (browser-only). If absent, browser-side logging is disabled. */
|
|
26
|
+
recaptchaSiteKey?: string;
|
|
27
|
+
/** reCAPTCHA action name; defaults to "log_error". */
|
|
28
|
+
recaptchaAction?: string;
|
|
29
|
+
/** Default source for events that don't pass an explicit source. */
|
|
30
|
+
defaultSource?: Source;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* One line item in `LogContext.charges` / `LogContext.recurringFees`.
|
|
34
|
+
*
|
|
35
|
+
* Sub-keys are allowlisted: `id` / `name` / `amount` / `cycle`. Anything else
|
|
36
|
+
* (memo, note, internal_comment, etc.) is stripped by the server-side
|
|
37
|
+
* `sanitizeIssueEventContext` hook before persistence.
|
|
38
|
+
*/
|
|
39
|
+
interface LogChargeLine {
|
|
40
|
+
id?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
amount?: number;
|
|
43
|
+
/** Only meaningful on `recurringFees`, e.g. "monthly". */
|
|
44
|
+
cycle?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Closed allowlist for log context fields.
|
|
48
|
+
*
|
|
49
|
+
* **Why this is a closed type (no index signature).** The PII contract for
|
|
50
|
+
* this logger is "never accept user-input data into the pipeline in the first
|
|
51
|
+
* place" — not "scrub it after". A closed type makes TypeScript reject unknown
|
|
52
|
+
* keys at every call site, so card numbers, names, emails, addresses, etc.
|
|
53
|
+
* cannot accidentally land in an event's `context`.
|
|
54
|
+
*
|
|
55
|
+
* Naming convention:
|
|
56
|
+
* - `se*` prefix → identifier from the SE API (matches SE's wire term)
|
|
57
|
+
* - `vendor*` prefix → identifier from the underlying property-management
|
|
58
|
+
* system (SiteLink / StorEdge / DoorSwap)
|
|
59
|
+
* - everything else → user-facing terms shared with the admin UI
|
|
60
|
+
* (e.g. `organizationId` matches the "Organization" label used in CMS)
|
|
61
|
+
*
|
|
62
|
+
* If a new context field is genuinely needed, add it here intentionally and
|
|
63
|
+
* confirm it carries no PII. The server has a defense-in-depth filter
|
|
64
|
+
* (`sanitizeIssueEventContext`) that drops unknown keys before persistence.
|
|
65
|
+
*/
|
|
66
|
+
interface LogContext {
|
|
67
|
+
/** Default source for events that don't pass an explicit source. */
|
|
68
|
+
source?: Source;
|
|
69
|
+
/** Anonymous browser session identifier. NEVER a logged-in user identity. */
|
|
70
|
+
sessionId?: string;
|
|
71
|
+
/** React component-tree path from `<ErrorBoundary>`. No user input. */
|
|
72
|
+
componentStack?: string;
|
|
73
|
+
/** Payload-side ID for the org (Mongo ObjectID). Maps 1:1 with the SE
|
|
74
|
+
* company below — they're two IDs for the same entity in different systems. */
|
|
75
|
+
organizationId?: string;
|
|
76
|
+
/** Display name, e.g. "Go Local Interactive". */
|
|
77
|
+
organizationName?: string;
|
|
78
|
+
/** SE-side numeric ID for the same org (e.g. 7). Used to pivot into SE admin. */
|
|
79
|
+
seCompanyId?: number;
|
|
80
|
+
/** SE renter UUID. SE calls this "tenant" — confusing in our multi-tenant
|
|
81
|
+
* CMS context, hence the `se` prefix. */
|
|
82
|
+
seTenantId?: string;
|
|
83
|
+
/** Vendor-system renter ID (SiteLink/StorEdge/DoorSwap). */
|
|
84
|
+
vendorTenantId?: string;
|
|
85
|
+
/** Which underlying property-management system the org uses. */
|
|
86
|
+
vendorType?: "SiteLink" | "StorEdge" | "DoorSwap";
|
|
87
|
+
seFacilityId?: string | number;
|
|
88
|
+
vendorFacilityId?: string | number;
|
|
89
|
+
/** Vendor-side site/region code. */
|
|
90
|
+
siteLocationCode?: string;
|
|
91
|
+
seUnitId?: string | number;
|
|
92
|
+
vendorUnitId?: string | number;
|
|
93
|
+
/** Unit category slug (e.g. "5x10-storage"). */
|
|
94
|
+
unitCategorySlug?: string;
|
|
95
|
+
/** Pricing tier tag, e.g. "Tier 1" / "Tier 2". */
|
|
96
|
+
unitTier?: string;
|
|
97
|
+
/** Rate plan family, e.g. "standard_rate" | "tiered_rate" | "channel_rate" | "managed_rate". */
|
|
98
|
+
ratePlan?: string;
|
|
99
|
+
seReservationId?: string;
|
|
100
|
+
vendorReservationId?: string | number;
|
|
101
|
+
/** Hard hold (units locked) vs soft inquiry. */
|
|
102
|
+
reservationType?: "hard" | "soft";
|
|
103
|
+
/** SE-side UUID on the `vendor_rentals` table. */
|
|
104
|
+
seRentalId?: string;
|
|
105
|
+
/** Vendor-system rental ID (e.g. "R-1234567"). */
|
|
106
|
+
vendorRentalId?: string;
|
|
107
|
+
/** SE move-in event / transaction ID. */
|
|
108
|
+
seTransactionId?: string | number;
|
|
109
|
+
/** Vendor's ledger ID, surfaced via SE's `_se_ledger_id`. */
|
|
110
|
+
seLedgerId?: string | number;
|
|
111
|
+
/** Payment receipt ID (SE `_se_receipt_id`). */
|
|
112
|
+
seReceiptId?: string | number;
|
|
113
|
+
/** Single charge ID when one specific line item is the focus of the error. */
|
|
114
|
+
chargeId?: string;
|
|
115
|
+
/** Current invoice / one-time charges. Sub-keys are allowlisted by
|
|
116
|
+
* `sanitizeIssueEventContext` — memo/note/comment fields are stripped. */
|
|
117
|
+
charges?: LogChargeLine[];
|
|
118
|
+
/** Recurring billing schedule. Same sub-key allowlist as `charges`. */
|
|
119
|
+
recurringFees?: LogChargeLine[];
|
|
120
|
+
promotionId?: string | number;
|
|
121
|
+
promotionSlug?: string;
|
|
122
|
+
insurancePlanId?: string | number;
|
|
123
|
+
paymentMethodType?: "cc" | "ach";
|
|
124
|
+
autopayEnabled?: boolean;
|
|
125
|
+
billingCycle?: "monthly" | "prepay";
|
|
126
|
+
/** ISO date the user picked. The date itself is not PII — it's a calendar
|
|
127
|
+
* click, not who-they-are. */
|
|
128
|
+
moveInDate?: string;
|
|
129
|
+
/** Numeric rate the user *saw* on the page. Useful for "user saw $X but
|
|
130
|
+
* was charged $Y" debugging without logging payment data. */
|
|
131
|
+
quotedRate?: number;
|
|
132
|
+
/** Which multi-step user flow the error occurred in. Pair with `step` —
|
|
133
|
+
* `step` is meaningless without a flow reference (step 3 of *what*?).
|
|
134
|
+
* Closed union so values stay grep-able across apps. */
|
|
135
|
+
flow?: "reservation" | "rental" | "cancellation" | "payment-update" | "onboarding";
|
|
136
|
+
/** Position within `flow` — number for ordered flows, slug for named ones.
|
|
137
|
+
* Meaningful only when paired with `flow`. Different from `slug` (which
|
|
138
|
+
* entity is in focus) and from the top-level `url` (where the user was). */
|
|
139
|
+
step?: number | string;
|
|
140
|
+
/** Stable identifier for the entity being acted on — page slug, market
|
|
141
|
+
* slug, unit-category slug, etc. Decoupled from URL: a build-time SSG
|
|
142
|
+
* error has no URL yet but the slug for the page being built does. */
|
|
143
|
+
slug?: string;
|
|
144
|
+
/** Which API/RPC was being called (e.g. "createReservationV2"). */
|
|
145
|
+
apiMethod?: string;
|
|
146
|
+
/** URL of the called endpoint, query string already stripped. */
|
|
147
|
+
apiEndpoint?: string;
|
|
148
|
+
httpStatus?: number;
|
|
149
|
+
/** Cache identifier when the error came from a stale-cache lookup. */
|
|
150
|
+
cacheKey?: string;
|
|
151
|
+
/** Mirrors `LogErrorOptions.reason` for filter convenience. */
|
|
152
|
+
errorTag?: string;
|
|
153
|
+
/** Closed schema field names, never user-typed values. e.g. `["cvv", "email"]`. */
|
|
154
|
+
validationFieldNames?: string[];
|
|
155
|
+
/** Soft-assertion expected count, e.g. "should have at least 1 unit, got 0". */
|
|
156
|
+
expectedCount?: number;
|
|
157
|
+
actualCount?: number;
|
|
158
|
+
collectionSlug?: string;
|
|
159
|
+
documentId?: string;
|
|
160
|
+
/** Which Payload hook fired the error (e.g. "beforeChange"). */
|
|
161
|
+
hookName?: string;
|
|
162
|
+
userRole?: "admin" | "super-admin" | "user" | "api-user";
|
|
163
|
+
/** AI-scraper batch ID. */
|
|
164
|
+
scraperBatchId?: string;
|
|
165
|
+
/** Build/deploy ID for build-trigger hooks. */
|
|
166
|
+
buildId?: string;
|
|
167
|
+
}
|
|
168
|
+
interface LogErrorOptions {
|
|
169
|
+
source?: Source;
|
|
170
|
+
severity?: Severity;
|
|
171
|
+
context?: LogContext;
|
|
172
|
+
/**
|
|
173
|
+
* Failure-classification code — the WHY behind the error. Closed enum
|
|
174
|
+
* (see `Reason`). Same code path failing for different reasons becomes
|
|
175
|
+
* distinct Issues, since `reason` is part of the fingerprint.
|
|
176
|
+
*
|
|
177
|
+
* If omitted, the event is uncaught/unclassified — fingerprint groups
|
|
178
|
+
* by `(source, message, top-stack-frame)` only.
|
|
179
|
+
*/
|
|
180
|
+
reason?: Reason;
|
|
181
|
+
}
|
|
182
|
+
interface LogEvent {
|
|
183
|
+
source: Source;
|
|
184
|
+
repo: Repo;
|
|
185
|
+
severity: Severity;
|
|
186
|
+
fingerprint: string;
|
|
187
|
+
message: string;
|
|
188
|
+
stack: string;
|
|
189
|
+
context: LogContext;
|
|
190
|
+
url: string;
|
|
191
|
+
userAgent: string;
|
|
192
|
+
occurredAt: string;
|
|
193
|
+
release?: string;
|
|
194
|
+
/** Failure-classification code copied from `LogErrorOptions.reason`. */
|
|
195
|
+
reason?: Reason;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export type { InitLoggerConfig as I, LogContext as L, Reason as R, Severity as S, LogErrorOptions as a, LogChargeLine as b, LogEvent as c, Repo as d, Source as e };
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@glidevvr/storage-payload-error-logger-pkg",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Centralized error capture for GLI storage products (theme, unit-table, reservation, rental, login). Publishes a runtime helper for browsers and Node, a React error boundary, and a Payload v3 endpoint handler.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./react": {
|
|
15
|
+
"types": "./dist/react/index.d.ts",
|
|
16
|
+
"import": "./dist/react/index.mjs",
|
|
17
|
+
"require": "./dist/react/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./payload-endpoint": {
|
|
20
|
+
"types": "./dist/payload-endpoint/index.d.ts",
|
|
21
|
+
"import": "./dist/payload-endpoint/index.mjs",
|
|
22
|
+
"require": "./dist/payload-endpoint/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"build:watch": "tsup --watch",
|
|
31
|
+
"test": "vitest run",
|
|
32
|
+
"test:watch": "vitest"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"payload": "3.81.0",
|
|
36
|
+
"react": "18 || 19"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"react": {
|
|
40
|
+
"optional": true
|
|
41
|
+
},
|
|
42
|
+
"payload": {
|
|
43
|
+
"optional": true
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
48
|
+
"@testing-library/react": "16.3.2",
|
|
49
|
+
"@types/node": "20",
|
|
50
|
+
"@types/react": "19",
|
|
51
|
+
"@types/react-dom": "19",
|
|
52
|
+
"jsdom": "26.1.0",
|
|
53
|
+
"react": "19.2.3",
|
|
54
|
+
"react-dom": "19.2.3",
|
|
55
|
+
"tsup": "8.5.1",
|
|
56
|
+
"typescript": "5",
|
|
57
|
+
"vitest": "2.1.9"
|
|
58
|
+
},
|
|
59
|
+
"type": "module",
|
|
60
|
+
"author": "Go Local Interactive",
|
|
61
|
+
"license": "ISC"
|
|
62
|
+
}
|