Skip to content

fix(server): parallel-safe migration vars, bearer-secret error propagation, duplicate static-check, dead code, health encode log, scheduled task path, runtime detection, version threading, unknown-event error, MV CONCURRENTLY in transaction #1067

Closed

Description

@cristim

Problem

Report 04 (server/config) and report 06 (analytics) have several medium/low/nit findings in `internal/server/` and `cmd/server/main.go` that were not included in the initial PR #1040 commits. This issue tracks the remaining FOLD-1040 bucket.

04-M3 — `migrationsTimeout`/`runMigrations` package globals are not parallel-safe

`internal/server/app.go:154,172`: Both are package-level vars overwritten by tests. Tests that modify them must not call `t.Parallel()`, a constraint the compiler cannot enforce. Moving them to struct fields (defaulted in the constructor) makes each Application instance self-contained and test-parallel-safe.

04-M4 — `resolveScheduledTaskSecret` errors are swallowed in bearer mode, surfacing as a misleading downstream error

`app.go:273-283,298-312,321`: When the SecretResolver lookup fails in bearer mode, the code falls back to the plaintext env var (normally empty in prod) and `buildScheduledAuth` then fails with "bearer mode requires SCHEDULED_TASK_SECRET" — pointing the operator at the wrong env var. The root-cause secret-resolution error is buried in the log. Fix: return `(string, error)` from `resolveScheduledTaskSecret` and propagate the error in bearer mode.

04-M5 — `determineRuntimeMode` reads `AWS_LAMBDA_RUNTIME_API` directly

`cmd/server/main.go:110`: Reads the env var the `runtime.IsLambda()` helper was introduced to encapsulate. A future change to detection logic silently misses this call site.

04-M6 — Two divergent static-file containment checks (Lambda vs HTTP)

`static.go:25-56` vs `static.go:77-111`: `spaHandler.ServeHTTP` (HTTP path) uses no explicit abs-prefix check; `resolveStaticFilePath` (Lambda path) uses `HasPrefix(absFile, absDir)` which is subtly weak (no trailing separator). Extract one correct shared helper with separator-aware prefix and use it from both paths.

04-L2 — `hasFileContent` is dead code

`static.go:189-197`: No production caller; misleading comment claims startup-validation use that never happens.

04-L4 — Health check silently discards `json.Encode` error

`health.go:66`: `json.NewEncoder(w).Encode(health)` return value is ignored. `handleScheduledHTTP` logs it; inconsistent. Log for parity.

04-L5 — Scheduled handler re-parses task type with manual string split

`http.go:143-152`: `parts[2]` re-derives the segment the mux already isolated. Use `strings.TrimPrefix` or `r.PathValue` instead.

04-N1 — Version threaded via env round-trip

`cmd/server/main.go:33`, `cmd/lambda/main.go:48`: Both push `Version` into `os.Setenv("VERSION",...)` so `LoadApplicationConfig` can read it back. Awkward; pass directly via `ApplicationConfig`.

04-N3 — `isLambdaRuntime()` wrapper has a "do not use" comment but is still called

`app.go:138-140,263,385`: Either inline `runtime.IsLambda()` at call sites or drop the deprecation note.

04-N4 — Unknown Lambda event defaults to scheduled without a distinct error

`lambda.go:43-45`: Unrecognised payload formats are silently treated as scheduled events, masking the real "unknown event shape" cause.

06-M4 — `REFRESH MATERIALIZED VIEW CONCURRENTLY` inside a migration transaction

`migrations/000003:162-177`, `server/handler.go:211`: PostgreSQL rejects `REFRESH MATERIALIZED VIEW CONCURRENTLY` inside a transaction block. The initial migration calls `refresh_savings_materialized_views()` which uses CONCURRENTLY — this will fail at first run. Fix: use plain (non-concurrent) refresh inside the migration (views are empty anyway); reserve CONCURRENTLY for the runtime scheduled-task path. Also improve error visibility at handler.go:211 (currently logged as Warning only).

Evidence

Source: code-review report 04 (server/config) findings M3-M6, L2, L4-L5, N1-N4 and report 06 finding M4. All files are in the `fix/server-transport-config` branch that PR #1040 modifies.

Fix

Implement as additional commits on PR #1040 branch. Regression tests for M3 (parallel-safe migration fields), M4 (bearer-mode error propagation), M5 (IsLambda call), and 06-M4 (migration transaction guard).

Closes after PR #1040 merges.

Activity

  1. added
    pr-createdA PR has been opened for this issue (dedup guard for the auto-PR loop)
    pr-mergedThe PR for this issue has been merged
    on Jun 7, 2026
  2. cristim commented on Jul 27, 2026

    @cristim
    MemberAuthor

    Verification sweep against main (101f099fb) on 2026-07-27 finds this already resolved.
    All of M3-M6, L2, L4-L5, N1, N3-N4 and 06-M4 have landed.
    Evidence: commit 69c5a0c (PR #1040).
    Recommending close.

  3. cristim commented on Sep 2, 2026

    @cristim
    MemberAuthor

    Verified resolved at 3c0f8ac: every item in this bucket has landed: migration timeout and runner are Application struct fields, resolveScheduledTaskSecret propagates its error, runtime detection goes through runtime.IsLambda(), both static-file paths share one separator-aware containment helper, hasFileContent and isLambdaRuntime are deleted, the health encoder error is logged, the scheduled path uses TrimPrefix, Version is passed directly, unknown Lambda events return a distinct error, and migration 000003 performs a non-concurrent initial refresh. Evidence: internal/server/app.go:86, internal/server/static.go:57, internal/server/lambda.go:46, internal/database/postgres/migrations/000003_analytics_partitions.up.sql:177 (#1040). Residual axes checked: Lambda and HTTP static paths both route through symlinkSafeContainedIn; refresh_savings_materialized_views() keeps CONCURRENTLY only for the runtime scheduled path outside a transaction. Closing as completed; reopen if the behaviour recurs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    effort/mDaysimpact/fewLimited audiencepr-createdA PR has been opened for this issue (dedup guard for the auto-PR loop)pr-mergedThe PR for this issue has been mergedpriority/p2Backlog-worthyseverity/mediumModerate harmtriagedItem has been triagedtype/bugDefecturgency/this-sprintWithin the current sprint

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions