chore/refactor #54

Merged
eliott merged 18 commits from chore/refactor into develop 2026-06-04 22:18:17 +02:00
Owner
No description provided.
Add the AGPL-3.0 license text and set the package.json license field
accordingly (was UNLICENSED).
Routine maintenance bump across NestJS, better-auth, and the test/build
toolchain (jest, ts-jest, prettier, tsx, typescript-eslint, etc.) with
the matching pnpm-lock.yaml update. No API-affecting changes.
feat(import): guard against zip bombs and cap request body size
Some checks failed
tests / test (pull_request) Failing after 1m22s
f6f1efe2c7
Reject a data.json whose declared uncompressed size exceeds
MAX_DATA_JSON_BYTES (64 MiB) before inflating, so a tiny compressed
entry cannot inflate to gigabytes and exhaust memory. Lower the upload
cap MAX_IMPORT_BYTES to 25 MiB (real exports are KB-to-low-MB) and set
explicit 128kb json/urlencoded body limits via AuthModule.forRoot so the
non-multipart bound is intentional rather than express's silent default.
Replace LICENSE with verbatim FSF AGPL-3.0 text
Some checks failed
tests / test (pull_request) Failing after 43s
01c383e0ae
chore: move to 0.x versioning (8.1.2 -> 0.8.1), rewrite changelog versions
Some checks failed
tests / test (pull_request) Failing after 42s
a4668d00c1
chore: drop redundant casts, fix generic .from() typing for drizzle 0.45
Some checks failed
tests / test (pull_request) Failing after 54s
a34e752f38
fix: construct the pg Pool explicitly so the pg dependency is imported
Some checks failed
tests / test (pull_request) Failing after 56s
14da48370d
From a full-codebase review:

- import: run wipe + import in a single transaction so a failed import can
  no longer destroy existing data with nothing restored; compensate orphaned
  accounts from a failed CreateNew import; make DataWipe atomic
- import: reject zip bombs before decompression (entry-count + declared and
  actual uncompressed-size caps) and lower the compressed upload cap
- import: structurally validate the cast-only export payload before any DB
  write, so malformed archives fail with 400 instead of a mid-tx 500
- import: per-route throttle on /import and /import/preview; stop echoing
  Better-Auth internals on account-creation failure
- crypto: version-tag random-IV ciphertext for unambiguous detection;
  document the deterministic-encryption leakage tradeoff
- http: ValidationPipe transform:true; expose X-Request-Id via CORS
- config: require SMTP vars in production; depth-guard the FK cause chain

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Each importer looped issuing a separate tx.insert per row, so a sizable
import meant hundreds-to-thousands of sequential round-trips holding the
import transaction (and its locks) open. Every row already gets an explicit
v7() id and no importer uses .returning(), so the per-row reuse/dedup logic
is unchanged — rows are now collected and flushed via a single chunked
batchInsert(tx, table, rows) per table. Identical ids, counts and label
reuse; far fewer round-trips.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Deleting any frame ran two full-shoot UPDATEs to recompact numbers to 1..N,
even when removing the highest-numbered frame. Numbers are distinct positive
integers, so the shoot is already gapless 1..N exactly when COUNT == MAX.
Check that cheaply after the delete and skip the rewrite when it holds (the
common case); only a gap left mid-sequence still falls back to the existing
negate-then-renumber two-pass. End state is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
planExport fired 11 COUNT(*) queries to populate meta.counts and then both
export paths re-read every row anyway. buildExport now derives counts from
the arrays it already collects; streamArchive tallies rows as they stream and
emits meta (with counts) last. Safe because the importer does a full
JSON.parse (key order irrelevant) and never reads meta.counts, so the archive
format is unchanged. Removes the now-dead countRows from PagedQuery.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- reference-validator: collapse the duplicated global/non-global branches in
  checkRef into a single query with a conditional column.
- shoot: route update/setPinned/setDone through one updateOwnedOrThrow helper
  instead of repeating the update-then-404 block three times.
- changelog: drop the pre-select existence check in update (TOCTOU); the
  UPDATE ... RETURNING already reports a missing row, and throwing before the
  item rewrite rolls the transaction back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reviewed-on: #53
The v2 action tag floats across near-daily fallow releases while the
action's cache step restores .fallow/ through a prefix fallback key, so
a cache written by one fallow version can be read by another and corrupt
the new-only gate's introduced/inherited attribution. Pinning the CLI
version and forcing --no-cache makes the audit verdict deterministic.
chore: clear fallow dead-dep findings and apply lint autofixes
Some checks failed
tests / test (pull_request) Failing after 54s
6fafb6d046
- ignore @nestjs/schematics (nest-cli collection), tsconfig-paths
  (test:debug -r register) and eslint-config-prettier (bundled via
  eslint-plugin-prettier/recommended) in .fallowrc.json: all three are
  toolchain usage invisible to import analysis
- remove @eslint/eslintrc and source-map-support: referenced nowhere in
  src, test, config or scripts
- drop two redundant type assertions flagged by the lockfile-pinned
  eslint --fix
refactor(export): track JSON separator instead of first-row flag in streamQuery
All checks were successful
tests / test (pull_request) Successful in 2m35s
d2223497b0
Drops the per-row ternary, taking streamQuery from CRAP 30.0 (gate
threshold) to under it. This was the one introduced finding failing the
fallow audit gate: the action passes a line-scoped diff (diff-filter
added), so touching lines inside an at-threshold function counts the
finding as introduced even though the function predates the PR.
eliott merged commit 7ebad8033a into develop 2026-06-04 22:18:17 +02:00
eliott deleted branch chore/refactor 2026-06-04 22:18:17 +02:00
Sign in to join this conversation.
No reviewers
No labels
run-ci
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
RollNote/rollnote-api!54
No description provided.