8000 Separate Portal app construction from listeners and background-job startup · Issue #539 · jra3/mulm · GitHub
[go: up one dir, main page]

Skip to content

Separate Portal app construction from listeners and background-job startup #539

Closed

Description

@jra3

Problem

src/index.ts constructs/configures Express, initializes storage, mounts routes, and eventually starts listeners and scheduled jobs in one module. Importing it is not a way to obtain a testable app. Route tests therefore build miniature apps, such as src/tests/route-renders.test.ts, which exercise handlers and templates but not the production middleware/mount order.

Proposed change

  1. Extract createApp(dependencies) returning the configured Express app with the real routes, view configuration, cookies, body parsing, session, origin/CSRF validation, rate limiters, and error behavior in their current order.
  2. Keep explicit initialization, HTTP/MCP listeners, and scheduled jobs in the executable entry point. Use Open and migrate the database on first use, not on import #432's memoized initialization and let failures reject before listening.
  3. Pass a narrow dependency object for environment/configuration and external effects that need test replacements. Use the real SQLite repositories for integration tests. Avoid a wholesale DI framework or rewriting every repository in this ticket.
  4. Make resource lifetimes explicit where bootstrap owns handles: cleanup on startup failure and teardown for tests. Constructing the Express app must not itself start job timers or listeners.
  5. Keep lightweight handler/template tests where useful; add a small set of full-app Supertest cases to catch mount-order or middleware regressions.

Acceptance criteria and tests

  • Importing the app factory or calling it starts no HTTP/MCP listener, scheduled job, or real R2/SMTP work.
  • Production startup initializes dependencies before accepting requests; migration/initialization failures prevent listening.
  • Tests exercise the actual mounted routes with a disposable database: anonymous/authenticated access, admin denial, an HTMX response, CSRF rejection, and valid session/CSRF success.
  • Explicit environment inputs preserve secure-cookie/proxy behavior and keep scheduled side effects live-production-only.
  • Existing route-render and security middleware suites still pass; add focused composition tests instead of duplicating all handler tests.
  • Typecheck/lint pass; startup usage and teardown are documented.

Dependencies and scope

Build on #432 for import-safe database initialization. This is a bounded implementation slice of #13, not a replacement for its remaining HTTP coverage. The current globally installed repository connection may remain behind the explicit initialization seam; do not claim two apps can use different databases concurrently until that is actually supported and tested. OAuth behavior, authentication policy, and hosting configuration do not change.

Review baseline

Source review at 78e0f1b2ff157e289c237d533f1406302d95118e. Repository typechecking and the focused specialty-award/level-progress tests passed during the review; these are not reproductions of the new failure scenarios above. Full database and E2E suites were not run.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestinfrastructureInfrastructure, deployment, and DevOpspriority:mediumMedium priority - important but not urgentready-for-agentFully specified, ready for an AFK agenttestingTesting, test coverage, and quality assurance

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0