nightytidy 0.3.7 → 0.3.9
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/bin/nightytidy.js +1 -1
- package/package.json +1 -1
- package/src/agent/git-integration.js +4 -1
- package/src/claude.js +1 -1
- package/src/prompts/manifest.json +138 -138
- package/src/prompts/steps/02-test-coverage.md +181 -181
- package/src/prompts/steps/03-test-hardening.md +181 -181
- package/src/prompts/steps/04-test-architecture.md +130 -130
- package/src/prompts/steps/05-test-consolidation.md +165 -165
- package/src/prompts/steps/06-test-quality.md +211 -211
- package/src/prompts/steps/07-api-design.md +165 -165
- package/src/prompts/steps/08-security-sweep.md +207 -207
- package/src/prompts/steps/09-dependency-health.md +217 -217
- package/src/prompts/steps/10-codebase-cleanup.md +189 -189
- package/src/prompts/steps/11-crosscutting-concerns.md +196 -196
- package/src/prompts/steps/12-file-decomposition.md +263 -263
- package/src/prompts/steps/13-code-elegance.md +329 -329
- package/src/prompts/steps/14-architectural-complexity.md +297 -297
- package/src/prompts/steps/15-type-safety.md +192 -192
- package/src/prompts/steps/16-logging-error-message.md +173 -173
- package/src/prompts/steps/17-data-integrity.md +139 -139
- package/src/prompts/steps/18-performance.md +183 -183
- package/src/prompts/steps/19-cost-resource-optimization.md +136 -136
- package/src/prompts/steps/20-error-recovery.md +145 -145
- package/src/prompts/steps/21-race-condition-audit.md +178 -178
- package/src/prompts/steps/22-bug-hunt.md +229 -229
- package/src/prompts/steps/23-frontend-quality.md +210 -210
- package/src/prompts/steps/24-uiux-audit.md +284 -284
- package/src/prompts/steps/25-state-management.md +170 -170
- package/src/prompts/steps/26-perceived-performance.md +190 -190
- package/src/prompts/steps/27-devops.md +165 -165
- package/src/prompts/steps/28-scheduled-job-chron-jobs.md +141 -141
- package/src/prompts/steps/29-observability.md +152 -152
- package/src/prompts/steps/30-backup-check.md +155 -155
- package/src/prompts/steps/31-product-polish-ux-friction.md +122 -122
- package/src/prompts/steps/32-feature-discovery-opportunity.md +128 -128
- package/src/prompts/steps/33-strategic-opportunities.md +217 -217
|
@@ -1,196 +1,196 @@
|
|
|
1
|
-
# Cross-Cutting Concerns Consistency Audit
|
|
2
|
-
|
|
3
|
-
Find patterns that should be identical across the codebase but have drifted. Other audits check within a single module; this one checks each pattern **across every instance, file, and layer** — drift between implementations is the bug.
|
|
4
|
-
|
|
5
|
-
Branch: `cross-cutting-consistency-[date]`. Report: `audit-reports/11_CROSS_CUTTING_CONSISTENCY_REPORT_[run-number]_[date]_[time in user's local time].md`.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Global Rules
|
|
10
|
-
|
|
11
|
-
- Run tests after every change. Commits: `fix: standardize [pattern] in [module]`
|
|
12
|
-
- Per concern: **(1)** find every instance, **(2)** identify dominant/best pattern, **(3)** catalog every deviation, **(4)** fix only mechanical low-risk deviations, **(5)** document everything else.
|
|
13
|
-
- **Only fix** when: canonical pattern is unambiguous, change is mechanical (not behavioral), code has test coverage, no API contract or user-facing behavior changes.
|
|
14
|
-
- **Do NOT fix**: public endpoint response shapes, business logic, untested code, or 50/50 splits (document both, recommend team decision).
|
|
15
|
-
- **Be exhaustive.** "37 of 40 endpoints use offset/limit, 3 use cursor-based" is valuable. "Most use offset/limit" is not. Count everything.
|
|
16
|
-
- For multi-tenancy and soft-delete: missing filters = potential data leak bugs. Treat as security-severity.
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## Phase 1: Pagination Consistency
|
|
21
|
-
|
|
22
|
-
Find every list/collection endpoint, query, UI list, and GraphQL connection. For each, catalog:
|
|
23
|
-
|
|
24
|
-
- **Strategy**: offset/limit, page/pageSize, cursor-based, keyset, or unbounded
|
|
25
|
-
- **Param names**: `page`/`limit`/`per_page`/`pageSize`/`cursor`/`after`/`next_token`/etc.
|
|
26
|
-
- **Defaults & max page size** (flag missing maximums)
|
|
27
|
-
- **Response metadata shape**: `{ total, page, pageSize }` vs `{ totalCount, hasMore, nextCursor }` vs wrapped vs none
|
|
28
|
-
- **Where logic lives**: handler, service, shared utility, ORM scope, inline
|
|
29
|
-
- **Edge cases**: page 0 vs 1, negative, beyond total, pageSize=0, pageSize=999999
|
|
30
|
-
|
|
31
|
-
**Safe fixes**: Add missing max page size limits. Align internal param names. Standardize metadata on internal endpoints. Add missing defaults.
|
|
32
|
-
|
|
33
|
-
**Report table**: Location | Type | Strategy | Params | Defaults | Max Size | Metadata Shape | Canonical? | Fixed?
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Phase 2: Sorting & Filtering Consistency
|
|
38
|
-
|
|
39
|
-
Find every sortable/filterable endpoint or dynamic query. Catalog:
|
|
40
|
-
|
|
41
|
-
- **Sort format**: `?sort=name` vs `?sort_by=name&order=asc` vs `?sort=name:asc` vs others
|
|
42
|
-
- **Multi-field sort** support and syntax
|
|
43
|
-
- **Default sort** (explicit or implicit insertion order = fragile)
|
|
44
|
-
- **Filter format**: `?status=active` vs `?filter[status]=active` vs others
|
|
45
|
-
- **Filter operators**: equality only or range/contains/in? Consistent syntax?
|
|
46
|
-
- **Search**: `?q=` vs `?search=` vs `?query=` — type (full-text, LIKE, regex) and which fields
|
|
47
|
-
- **Validation**: sort fields checked against allowlist? (Flag missing allowlists)
|
|
48
|
-
- **SQL injection risk**: dynamic fields parameterized or concatenated? (**CRITICAL** if concatenated)
|
|
49
|
-
|
|
50
|
-
**Safe fixes**: Standardize internal param names. Add missing sort field allowlists. Add default sorts. Fix SQL injection risks.
|
|
51
|
-
|
|
52
|
-
**Report table**: Location | Sort Format | Filter Format | Search Format | Default Sort | Validated? | Canonical?
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
## Phase 3: Soft Delete & Data Lifecycle Consistency
|
|
57
|
-
|
|
58
|
-
Find every deletion operation (DELETE queries, `.destroy()`/`.delete()`, status→deleted/archived, `deleted_at`/`is_deleted` updates, hard deletes). Catalog:
|
|
59
|
-
|
|
60
|
-
- **Strategy**: hard delete, soft delete (timestamp vs boolean vs status-based), or mixed
|
|
61
|
-
- **Field used**: `deleted_at` vs `deletedAt` vs `is_deleted` vs `status` vs `active` (inverted)
|
|
62
|
-
- **Query filtering**: do ALL read queries on soft-delete tables exclude deleted records? (Missing filters = silent data integrity bugs)
|
|
63
|
-
- **Unique constraints**: can soft-deleted records block new records with same unique field?
|
|
64
|
-
- **Cascade**: parent soft-deleted → children soft-deleted? hard-deleted? orphaned?
|
|
65
|
-
- **Restoration path**, permanent purge process
|
|
66
|
-
- **API behavior**: DELETE returns what? GET on deleted record returns 404, 410, or flagged record?
|
|
67
|
-
|
|
68
|
-
**Most dangerous drift**: some queries filtering soft-deleted records, others not.
|
|
69
|
-
|
|
70
|
-
**Safe fixes**: Add missing `WHERE deleted_at IS NULL`. Standardize field names via migration files (don't run).
|
|
71
|
-
|
|
72
|
-
**Report table**: Entity | Strategy | Field | All Queries Filter? | Cascade | Unique Constraint Issue? | Restoration? | Purge?
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## Phase 4: Audit Logging & Activity Tracking Consistency
|
|
77
|
-
|
|
78
|
-
Find every audit mechanism (audit tables, activity feeds, event tracking, `created_by`/`updated_by` fields, timestamps, change history, webhooks). For every create/update/delete on every significant entity, catalog:
|
|
79
|
-
|
|
80
|
-
- **Is it logged?** Via what mechanism?
|
|
81
|
-
- **What's captured?** Actor, action, target, timestamp, before/after values, IP/session context
|
|
82
|
-
- **Where logged?** Inline, middleware, ORM hook, DB trigger, event subscriber
|
|
83
|
-
- **Storage & retention**
|
|
84
|
-
|
|
85
|
-
**Flag operations with no audit trail**, especially: user data changes, permission/role changes, financial ops, admin actions, auth events, data exports, config changes, deletions.
|
|
86
|
-
|
|
87
|
-
**Safe fixes**: Add missing `updated_at` auto-update. Populate `created_by`/`updated_by` where pattern exists but was missed. Add audit entries for unlogged critical ops using existing mechanism. Do NOT introduce new audit mechanisms.
|
|
88
|
-
|
|
89
|
-
**Report table**: Entity | Create Logged? | Update Logged? (diff?) | Delete Logged? | Actor Captured? | Mechanism | Gaps
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Phase 5: Timezone & Date/Time Handling Consistency
|
|
94
|
-
|
|
95
|
-
Find every date/time operation (creation, parsing, formatting, storage, comparison, arithmetic, timezone conversion, display). Catalog:
|
|
96
|
-
|
|
97
|
-
- **Storage TZ**: UTC, server-local, user-local, mixed? Column types: `TIMESTAMP` vs `TIMESTAMPTZ` vs `DATETIME` vs `VARCHAR`?
|
|
98
|
-
- **Library**: `Date`, `moment`, `date-fns`, `dayjs`, `luxon` — multiple in use?
|
|
99
|
-
- **Server-side creation**: `new Date()` (server TZ), `Date.now()`, `moment.utc()`, DB `NOW()`?
|
|
100
|
-
- **User display**: converted to user TZ? Where does user TZ come from?
|
|
101
|
-
- **API format**: ISO 8601? Unix timestamps? Locale strings? Mixed?
|
|
102
|
-
- **Date-only values**: stored as datetime (midnight of which TZ?), date type, or string?
|
|
103
|
-
- **DST handling**: adds 24 hours (wrong) or 1 calendar day (right)?
|
|
104
|
-
- **Date boundaries**: "today's records" — whose today?
|
|
105
|
-
|
|
106
|
-
**Dangerous drift**: some DB columns UTC, others server-local (invisible until multi-zone or DST). Mixed API date formats.
|
|
107
|
-
|
|
108
|
-
**Safe fixes**: Replace `new Date()` with UTC equivalents per convention. Standardize internal API dates to ISO 8601. Add TZ-aware column types in migration files. Replace deprecated date library usage.
|
|
109
|
-
|
|
110
|
-
**Report table**: Location | Operation | Library | Timezone | Format | Storage Type | Canonical? | Risk
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Phase 6: Currency & Numeric Precision Consistency
|
|
115
|
-
|
|
116
|
-
**Skip if app doesn't handle money/prices/precision-sensitive numbers. State why.**
|
|
117
|
-
|
|
118
|
-
Find every monetary/precision operation. Catalog:
|
|
119
|
-
|
|
120
|
-
- **Storage**: integer cents, `DECIMAL(x,y)`, `FLOAT`, string?
|
|
121
|
-
- **Code representation**: float, BigDecimal, integer cents, money library?
|
|
122
|
-
- **Arithmetic**: float math (precision loss), integer math (truncation), library-based?
|
|
123
|
-
- **Rounding**: method and consistency
|
|
124
|
-
- **Currency**: hardcoded, per-record, configurable?
|
|
125
|
-
- **Display & API format**: consistent?
|
|
126
|
-
|
|
127
|
-
**Dangerous drift**: mixing float and integer cents (off-by-one-cent bugs at scale).
|
|
128
|
-
|
|
129
|
-
**Report table**: Location | Value Type | Storage | Code Rep | Arithmetic | Rounding | Display | Canonical? | Precision Risk?
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## Phase 7: Multi-Tenancy & Data Isolation Consistency
|
|
134
|
-
|
|
135
|
-
**Skip if single-tenant with no org/workspace/team concept. State why.**
|
|
136
|
-
|
|
137
|
-
Identify tenancy model (row-level `tenant_id`, schema-per-tenant, etc.). For every query, endpoint, and background job, audit:
|
|
138
|
-
|
|
139
|
-
- **Tenant scoping applied?** Via middleware (automatic) or manual per-query?
|
|
140
|
-
- **Bypassable?** Can developers write unscoped queries?
|
|
141
|
-
- **Background jobs**: receive and enforce tenant context?
|
|
142
|
-
- **Caches, file storage, search indexes**: tenant-scoped?
|
|
143
|
-
- **Unique constraints**: scoped to tenant?
|
|
144
|
-
|
|
145
|
-
**Missing tenant scoping on user-data table = CRITICAL cross-tenant data exposure.**
|
|
146
|
-
|
|
147
|
-
**Report table**: Entity | Has tenant_id? | Scoping Method | All Queries Scoped? | Cache Scoped? | Files Scoped? | Gaps
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
## Phase 8: Error Response & Status Code Consistency
|
|
152
|
-
|
|
153
|
-
For each scenario below, find every occurrence across all endpoints and compare responses:
|
|
154
|
-
|
|
155
|
-
**Scenarios**: Validation failure (400 vs 422, shape), Not found (404), Not authorized (401 vs 403), Forbidden, Conflict/duplicate (409 vs 400), Rate limited (429 + headers), Internal error (500, detail leakage), Method not allowed (405), Request too large (413)
|
|
156
|
-
|
|
157
|
-
For each: catalog dominant response, deviations (with location), and whether deviation is intentional.
|
|
158
|
-
|
|
159
|
-
**Safe fixes**: Align error responses on internal endpoints to dominant pattern.
|
|
160
|
-
|
|
161
|
-
**Report table per scenario**: Endpoint | Status Code | Response Shape | Message | Canonical? | Fixed?
|
|
162
|
-
|
|
163
|
-
---
|
|
164
|
-
|
|
165
|
-
## Phase 9: Synthesis & Drift Map
|
|
166
|
-
|
|
167
|
-
### Drift Heat Map
|
|
168
|
-
Rate each concern: **Consistent** (90%+), **Minor drift** (70-90%), **Significant drift** (50-70%), **No standard** (<50%).
|
|
169
|
-
|
|
170
|
-
### Root Cause Analysis
|
|
171
|
-
Per area with significant drift: missing shared utility? Convention changed over time? Different developer conventions? Pattern never decided?
|
|
172
|
-
|
|
173
|
-
### Prevention Recommendations
|
|
174
|
-
Per concern: shared utility to build, linter rule to enforce, code review checklist item, documentation to write.
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## Chat Output Requirement
|
|
179
|
-
|
|
180
|
-
Print a summary in conversation (don't make user open the report):
|
|
181
|
-
|
|
182
|
-
1. **Status Line** — What you did, whether tests pass.
|
|
183
|
-
2. **Key Findings** — Specific, actionable bullets with severity. Lead with impact.
|
|
184
|
-
- ✅ "CRITICAL: 4 of 22 queries on `orders` don't filter `deleted_at` — soft-deleted orders appear in invoices."
|
|
185
|
-
- ❌ "Found some inconsistencies with soft deletes."
|
|
186
|
-
3. **Changes Made** (if any) — Bullet list. Skip for read-only runs.
|
|
187
|
-
4. **Drift Heat Map** — Summary table from report.
|
|
188
|
-
5. **Recommendations** — Table (only if warranted):
|
|
189
|
-
|
|
190
|
-
| # | Recommendation | Impact | Risk if Ignored | Worth Doing? | Details |
|
|
191
|
-
|---|---|---|---|---|---|
|
|
192
|
-
| *n* | *≤10 words* | *What improves* | *Low/Med/High/Critical* | *Yes/Probably/Only if time* | *1–3 sentences* |
|
|
193
|
-
|
|
194
|
-
Order by risk descending. Be honest in "Worth Doing?" — not everything is worth the engineering time.
|
|
195
|
-
|
|
196
|
-
6. **Report Location** — Full path to detailed report.
|
|
1
|
+
# Cross-Cutting Concerns Consistency Audit
|
|
2
|
+
|
|
3
|
+
Find patterns that should be identical across the codebase but have drifted. Other audits check within a single module; this one checks each pattern **across every instance, file, and layer** — drift between implementations is the bug.
|
|
4
|
+
|
|
5
|
+
Branch: `cross-cutting-consistency-[date]`. Report: `audit-reports/11_CROSS_CUTTING_CONSISTENCY_REPORT_[run-number]_[date]_[time in user's local time].md`.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Global Rules
|
|
10
|
+
|
|
11
|
+
- Run tests after every change. Commits: `fix: standardize [pattern] in [module]`
|
|
12
|
+
- Per concern: **(1)** find every instance, **(2)** identify dominant/best pattern, **(3)** catalog every deviation, **(4)** fix only mechanical low-risk deviations, **(5)** document everything else.
|
|
13
|
+
- **Only fix** when: canonical pattern is unambiguous, change is mechanical (not behavioral), code has test coverage, no API contract or user-facing behavior changes.
|
|
14
|
+
- **Do NOT fix**: public endpoint response shapes, business logic, untested code, or 50/50 splits (document both, recommend team decision).
|
|
15
|
+
- **Be exhaustive.** "37 of 40 endpoints use offset/limit, 3 use cursor-based" is valuable. "Most use offset/limit" is not. Count everything.
|
|
16
|
+
- For multi-tenancy and soft-delete: missing filters = potential data leak bugs. Treat as security-severity.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Phase 1: Pagination Consistency
|
|
21
|
+
|
|
22
|
+
Find every list/collection endpoint, query, UI list, and GraphQL connection. For each, catalog:
|
|
23
|
+
|
|
24
|
+
- **Strategy**: offset/limit, page/pageSize, cursor-based, keyset, or unbounded
|
|
25
|
+
- **Param names**: `page`/`limit`/`per_page`/`pageSize`/`cursor`/`after`/`next_token`/etc.
|
|
26
|
+
- **Defaults & max page size** (flag missing maximums)
|
|
27
|
+
- **Response metadata shape**: `{ total, page, pageSize }` vs `{ totalCount, hasMore, nextCursor }` vs wrapped vs none
|
|
28
|
+
- **Where logic lives**: handler, service, shared utility, ORM scope, inline
|
|
29
|
+
- **Edge cases**: page 0 vs 1, negative, beyond total, pageSize=0, pageSize=999999
|
|
30
|
+
|
|
31
|
+
**Safe fixes**: Add missing max page size limits. Align internal param names. Standardize metadata on internal endpoints. Add missing defaults.
|
|
32
|
+
|
|
33
|
+
**Report table**: Location | Type | Strategy | Params | Defaults | Max Size | Metadata Shape | Canonical? | Fixed?
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Phase 2: Sorting & Filtering Consistency
|
|
38
|
+
|
|
39
|
+
Find every sortable/filterable endpoint or dynamic query. Catalog:
|
|
40
|
+
|
|
41
|
+
- **Sort format**: `?sort=name` vs `?sort_by=name&order=asc` vs `?sort=name:asc` vs others
|
|
42
|
+
- **Multi-field sort** support and syntax
|
|
43
|
+
- **Default sort** (explicit or implicit insertion order = fragile)
|
|
44
|
+
- **Filter format**: `?status=active` vs `?filter[status]=active` vs others
|
|
45
|
+
- **Filter operators**: equality only or range/contains/in? Consistent syntax?
|
|
46
|
+
- **Search**: `?q=` vs `?search=` vs `?query=` — type (full-text, LIKE, regex) and which fields
|
|
47
|
+
- **Validation**: sort fields checked against allowlist? (Flag missing allowlists)
|
|
48
|
+
- **SQL injection risk**: dynamic fields parameterized or concatenated? (**CRITICAL** if concatenated)
|
|
49
|
+
|
|
50
|
+
**Safe fixes**: Standardize internal param names. Add missing sort field allowlists. Add default sorts. Fix SQL injection risks.
|
|
51
|
+
|
|
52
|
+
**Report table**: Location | Sort Format | Filter Format | Search Format | Default Sort | Validated? | Canonical?
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Phase 3: Soft Delete & Data Lifecycle Consistency
|
|
57
|
+
|
|
58
|
+
Find every deletion operation (DELETE queries, `.destroy()`/`.delete()`, status→deleted/archived, `deleted_at`/`is_deleted` updates, hard deletes). Catalog:
|
|
59
|
+
|
|
60
|
+
- **Strategy**: hard delete, soft delete (timestamp vs boolean vs status-based), or mixed
|
|
61
|
+
- **Field used**: `deleted_at` vs `deletedAt` vs `is_deleted` vs `status` vs `active` (inverted)
|
|
62
|
+
- **Query filtering**: do ALL read queries on soft-delete tables exclude deleted records? (Missing filters = silent data integrity bugs)
|
|
63
|
+
- **Unique constraints**: can soft-deleted records block new records with same unique field?
|
|
64
|
+
- **Cascade**: parent soft-deleted → children soft-deleted? hard-deleted? orphaned?
|
|
65
|
+
- **Restoration path**, permanent purge process
|
|
66
|
+
- **API behavior**: DELETE returns what? GET on deleted record returns 404, 410, or flagged record?
|
|
67
|
+
|
|
68
|
+
**Most dangerous drift**: some queries filtering soft-deleted records, others not.
|
|
69
|
+
|
|
70
|
+
**Safe fixes**: Add missing `WHERE deleted_at IS NULL`. Standardize field names via migration files (don't run).
|
|
71
|
+
|
|
72
|
+
**Report table**: Entity | Strategy | Field | All Queries Filter? | Cascade | Unique Constraint Issue? | Restoration? | Purge?
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Phase 4: Audit Logging & Activity Tracking Consistency
|
|
77
|
+
|
|
78
|
+
Find every audit mechanism (audit tables, activity feeds, event tracking, `created_by`/`updated_by` fields, timestamps, change history, webhooks). For every create/update/delete on every significant entity, catalog:
|
|
79
|
+
|
|
80
|
+
- **Is it logged?** Via what mechanism?
|
|
81
|
+
- **What's captured?** Actor, action, target, timestamp, before/after values, IP/session context
|
|
82
|
+
- **Where logged?** Inline, middleware, ORM hook, DB trigger, event subscriber
|
|
83
|
+
- **Storage & retention**
|
|
84
|
+
|
|
85
|
+
**Flag operations with no audit trail**, especially: user data changes, permission/role changes, financial ops, admin actions, auth events, data exports, config changes, deletions.
|
|
86
|
+
|
|
87
|
+
**Safe fixes**: Add missing `updated_at` auto-update. Populate `created_by`/`updated_by` where pattern exists but was missed. Add audit entries for unlogged critical ops using existing mechanism. Do NOT introduce new audit mechanisms.
|
|
88
|
+
|
|
89
|
+
**Report table**: Entity | Create Logged? | Update Logged? (diff?) | Delete Logged? | Actor Captured? | Mechanism | Gaps
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Phase 5: Timezone & Date/Time Handling Consistency
|
|
94
|
+
|
|
95
|
+
Find every date/time operation (creation, parsing, formatting, storage, comparison, arithmetic, timezone conversion, display). Catalog:
|
|
96
|
+
|
|
97
|
+
- **Storage TZ**: UTC, server-local, user-local, mixed? Column types: `TIMESTAMP` vs `TIMESTAMPTZ` vs `DATETIME` vs `VARCHAR`?
|
|
98
|
+
- **Library**: `Date`, `moment`, `date-fns`, `dayjs`, `luxon` — multiple in use?
|
|
99
|
+
- **Server-side creation**: `new Date()` (server TZ), `Date.now()`, `moment.utc()`, DB `NOW()`?
|
|
100
|
+
- **User display**: converted to user TZ? Where does user TZ come from?
|
|
101
|
+
- **API format**: ISO 8601? Unix timestamps? Locale strings? Mixed?
|
|
102
|
+
- **Date-only values**: stored as datetime (midnight of which TZ?), date type, or string?
|
|
103
|
+
- **DST handling**: adds 24 hours (wrong) or 1 calendar day (right)?
|
|
104
|
+
- **Date boundaries**: "today's records" — whose today?
|
|
105
|
+
|
|
106
|
+
**Dangerous drift**: some DB columns UTC, others server-local (invisible until multi-zone or DST). Mixed API date formats.
|
|
107
|
+
|
|
108
|
+
**Safe fixes**: Replace `new Date()` with UTC equivalents per convention. Standardize internal API dates to ISO 8601. Add TZ-aware column types in migration files. Replace deprecated date library usage.
|
|
109
|
+
|
|
110
|
+
**Report table**: Location | Operation | Library | Timezone | Format | Storage Type | Canonical? | Risk
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Phase 6: Currency & Numeric Precision Consistency
|
|
115
|
+
|
|
116
|
+
**Skip if app doesn't handle money/prices/precision-sensitive numbers. State why.**
|
|
117
|
+
|
|
118
|
+
Find every monetary/precision operation. Catalog:
|
|
119
|
+
|
|
120
|
+
- **Storage**: integer cents, `DECIMAL(x,y)`, `FLOAT`, string?
|
|
121
|
+
- **Code representation**: float, BigDecimal, integer cents, money library?
|
|
122
|
+
- **Arithmetic**: float math (precision loss), integer math (truncation), library-based?
|
|
123
|
+
- **Rounding**: method and consistency
|
|
124
|
+
- **Currency**: hardcoded, per-record, configurable?
|
|
125
|
+
- **Display & API format**: consistent?
|
|
126
|
+
|
|
127
|
+
**Dangerous drift**: mixing float and integer cents (off-by-one-cent bugs at scale).
|
|
128
|
+
|
|
129
|
+
**Report table**: Location | Value Type | Storage | Code Rep | Arithmetic | Rounding | Display | Canonical? | Precision Risk?
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Phase 7: Multi-Tenancy & Data Isolation Consistency
|
|
134
|
+
|
|
135
|
+
**Skip if single-tenant with no org/workspace/team concept. State why.**
|
|
136
|
+
|
|
137
|
+
Identify tenancy model (row-level `tenant_id`, schema-per-tenant, etc.). For every query, endpoint, and background job, audit:
|
|
138
|
+
|
|
139
|
+
- **Tenant scoping applied?** Via middleware (automatic) or manual per-query?
|
|
140
|
+
- **Bypassable?** Can developers write unscoped queries?
|
|
141
|
+
- **Background jobs**: receive and enforce tenant context?
|
|
142
|
+
- **Caches, file storage, search indexes**: tenant-scoped?
|
|
143
|
+
- **Unique constraints**: scoped to tenant?
|
|
144
|
+
|
|
145
|
+
**Missing tenant scoping on user-data table = CRITICAL cross-tenant data exposure.**
|
|
146
|
+
|
|
147
|
+
**Report table**: Entity | Has tenant_id? | Scoping Method | All Queries Scoped? | Cache Scoped? | Files Scoped? | Gaps
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Phase 8: Error Response & Status Code Consistency
|
|
152
|
+
|
|
153
|
+
For each scenario below, find every occurrence across all endpoints and compare responses:
|
|
154
|
+
|
|
155
|
+
**Scenarios**: Validation failure (400 vs 422, shape), Not found (404), Not authorized (401 vs 403), Forbidden, Conflict/duplicate (409 vs 400), Rate limited (429 + headers), Internal error (500, detail leakage), Method not allowed (405), Request too large (413)
|
|
156
|
+
|
|
157
|
+
For each: catalog dominant response, deviations (with location), and whether deviation is intentional.
|
|
158
|
+
|
|
159
|
+
**Safe fixes**: Align error responses on internal endpoints to dominant pattern.
|
|
160
|
+
|
|
161
|
+
**Report table per scenario**: Endpoint | Status Code | Response Shape | Message | Canonical? | Fixed?
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Phase 9: Synthesis & Drift Map
|
|
166
|
+
|
|
167
|
+
### Drift Heat Map
|
|
168
|
+
Rate each concern: **Consistent** (90%+), **Minor drift** (70-90%), **Significant drift** (50-70%), **No standard** (<50%).
|
|
169
|
+
|
|
170
|
+
### Root Cause Analysis
|
|
171
|
+
Per area with significant drift: missing shared utility? Convention changed over time? Different developer conventions? Pattern never decided?
|
|
172
|
+
|
|
173
|
+
### Prevention Recommendations
|
|
174
|
+
Per concern: shared utility to build, linter rule to enforce, code review checklist item, documentation to write.
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Chat Output Requirement
|
|
179
|
+
|
|
180
|
+
Print a summary in conversation (don't make user open the report):
|
|
181
|
+
|
|
182
|
+
1. **Status Line** — What you did, whether tests pass.
|
|
183
|
+
2. **Key Findings** — Specific, actionable bullets with severity. Lead with impact.
|
|
184
|
+
- ✅ "CRITICAL: 4 of 22 queries on `orders` don't filter `deleted_at` — soft-deleted orders appear in invoices."
|
|
185
|
+
- ❌ "Found some inconsistencies with soft deletes."
|
|
186
|
+
3. **Changes Made** (if any) — Bullet list. Skip for read-only runs.
|
|
187
|
+
4. **Drift Heat Map** — Summary table from report.
|
|
188
|
+
5. **Recommendations** — Table (only if warranted):
|
|
189
|
+
|
|
190
|
+
| # | Recommendation | Impact | Risk if Ignored | Worth Doing? | Details |
|
|
191
|
+
|---|---|---|---|---|---|
|
|
192
|
+
| *n* | *≤10 words* | *What improves* | *Low/Med/High/Critical* | *Yes/Probably/Only if time* | *1–3 sentences* |
|
|
193
|
+
|
|
194
|
+
Order by risk descending. Be honest in "Worth Doing?" — not everything is worth the engineering time.
|
|
195
|
+
|
|
196
|
+
6. **Report Location** — Full path to detailed report.
|