Skip to content

fix(file-store): FileStore contract on local, AWS_REGION on s3, and doc corrections - #10

Merged
saby1101 merged 5 commits into
mainfrom
fix/filestore-contract
Aug 14, 2026
Merged

saby1101 merged 5 commits into
mainfrom
fix/filestore-contract

Conversation

@saby1101

@saby1101 saby1101 commented Aug 14, 2026 •

Copy link
Copy Markdown
Member

Fixes #7, #8 and #9 — the pre-existing bugs surfaced while writing exhaustive branch coverage in #6 — plus the stale documentation that PR left behind. No version bump here.

Based on chore/fastify-plugin-6, not main, since it builds on that branch's tests. Retarget to main once #6 merges.

#7 — LocalFileStore contract

exists rejected on a missing file instead of returning false, diverging from all four other providers and breaking callers written against exists(): Promise<boolean> — wms panel-gateway/src/plugin-reports/reports.route.ts:169 could never reach its not-found branch. Now catches ENOENT and returns false, rethrowing anything else.

save wrote directly while its siblings copyFromStream and copyFromLocalFile both mkdir(dirname, { recursive: true }) first, so nested keys threw ENOENT. wms saves to nested keys throughout (media/…, reports/…). Now mkdirs to match.

The old behaviour was pinned by a test that documented the bug — file-store.spec.ts asserted rejects.toThrow() with the comment "The current implementation throws for non-existent files, so test that". That assertion now checks the contract.

#8 — AWS_REGION was silently ignored

ConfigureAWS always passed region explicitly, so the SDK's own resolution chain never ran — and that chain is what reads the conventional AWS_REGION/AWS_DEFAULT_REGION. A pod configured the standard way silently got us-east-1 and cross-region requests, with no error. Now AWS_S3_REGION ?? AWS_REGION ?? "us-east-1", with README.md updated to document the precedence.

That the pre-existing spec set AWS_REGION against code which never read it suggests this had already caught someone.

#9 — S3 tidy-up

  • S3.NoSuchKey → S3.NotFound in exists and getInfo. NoSuchKey is modelled on GetObject (GetObjectCommand.d.ts:297) while HeadObject throws NotFound (HeadObjectCommand.d.ts:271), so those arms could never match. The $metadata 404 check kept as the fallback.
  • getInfo missing-timestamp fallback new Date() → new Date(0). Worth noting ISSUES.md records LOW-02 as already having made this exact change for Azure and GCP in 96d40d4 — S3 was simply missed, so this completes it rather than introducing a new convention.
  • ConfigureAWS validates S3_BUCKET before constructing the client, matching ConfigureMinio.

Documentation

CLAUDE.md still described the event-bus plugin removed in c001efc, including test:rabbitmq / test:integration / test:all scripts that package.json does not define. .claude/skills/gen-test/SKILL.md instructed agents to use testcontainers, which #6 removes — an active trap for the next agent. Both now describe the lazy SDK loading and the ts-jest sourceMap override, since either is easy to undo by accident and the second silently corrupts coverage numbers.

.claude/skills/release/SKILL.md claimed pushing to main triggers publishing; the workflow runs on: release: [created]. It now also records that version bumps belong on main rather than in a feature PR, and that tags come from the release — the convention this PR pair had to be rebuilt to respect.

pnpm-workspace.yaml still permitted build scripts for cpu-features, protobufjs and ssh2, all of which arrived via testcontainers and are now absent from the tree.

Verification

127 tests (up from 121), 100% coverage held on statements, branches, functions and lines. Each fix has a regression test that fails if reverted. Confirmed against the built dist/:

exists(missing)   -> false        (was: THREW ENOENT)
save("a/b/c.txt") -> ok           (was: THREW ENOENT)
AWS_REGION        -> eu-central-1 (was: us-east-1)

exists and the timestamp fallback are behaviour changes. Both move toward the documented interface and away from provider-specific surprises, but they are visible to anyone who had coded around the old behaviour.

Local issue tracking removed

ISSUES.md is deleted — issues are tracked on GitHub. Its one open finding (MED-01: src/types.ts does not augment FastifyInstance with FileStore) is filed as #11, including the wms declaration-merge risk that has kept it unfixed: wms already declares that exact property at libraries/framework/src/index.ts:58, so the augmentation needs verifying against a real wms build before it ships. The rest of the file was audit history, which belongs in issue threads and resolving PRs. CLAUDE.md records the convention.

@saby1101 saby1101 changed the title fix(file-store): FileStore contract on local, AWS_REGION on s3 fix(file-store): FileStore contract on local, AWS_REGION on s3, and doc corrections Aug 14, 2026
Base automatically changed from chore/fastify-plugin-6 to main August 14, 2026 10:19
saby1101 and others added 3 commits August 14, 2026 10:24
…ON on s3

LocalFileStore.exists rejected on a missing file instead of returning false, and
save wrote without creating parent directories though copyFromStream and
copyFromLocalFile both mkdir first. Callers written against the interface took the
wrong path on the LOCAL platform.

ConfigureAWS always passed a region, so the SDK's own resolution chain never ran and
a pod configured with the conventional AWS_REGION silently used us-east-1.

Also names S3.NotFound rather than S3.NoSuchKey, which is modelled on GetObject and
could never match a HeadObject failure; aligns the missing-timestamp fallback with
Azure and GCP; and validates S3_BUCKET before building the client.

Fixes #7, #8, #9

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CLAUDE.md still documented the event-bus plugin removed in c001efc, along with
test:rabbitmq / test:integration / test:all scripts that package.json does not
define. The gen-test skill instructed agents to reach for testcontainers, which is
no longer a dependency. Both now describe the lazy SDK loading and the ts-jest
sourceMap override, since either is easy to undo by accident.

The release skill claimed a push to main triggers publishing; the workflow actually
runs on release:created. Recorded that version bumps belong on main rather than in a
feature PR, and that tags come from the release.

pnpm-workspace.yaml still allowed build scripts for cpu-features, protobufjs and
ssh2, all of which arrived via testcontainers and are gone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The file carried one open finding (MED-01, no FastifyInstance augmentation), now
filed as #11 with the wms declaration-merge risk that has kept it unfixed. The rest
was audit history — dates scanned, fixed entries, a false positive — which belongs in
issue threads and the PRs that resolved it, not in a tracked file that silently goes
stale.

CLAUDE.md records the convention so it does not come back.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@saby1101
saby1101 force-pushed the fix/filestore-contract branch from 5a57080 to 2f15a83 Compare August 14, 2026 10:24
Nothing pinned what this package shipped. .gitignore excluded every lockfile and all
three CI jobs ran npm install, so each test run, build and publish resolved fresh from
the registry — the published artifact was never built from a reviewed tree, and a bad
transitive release would land with no diff to show for it. This package runs in every
wms service, so that reproducibility gap matters.

Standardises on pnpm to match the rest of the org, pinned by packageManager, and moves
CI to pnpm install --frozen-lockfile. Node version comes from one env value per
workflow instead of being repeated three times.

CONTRIBUTING said to tag releases with npm version, contradicting the release skill and
the actual publish trigger; rewritten to match how releases really work.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
chore(ci): commit pnpm-lock.yaml and install frozen
@saby1101
saby1101 merged commit 3e812f8 into main Aug 14, 2026
1 check passed
@saby1101
saby1101 deleted the fix/filestore-contract branch August 14, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LocalFileStore violates the FileStore contract on exists() and save()

1 participant