Skip to content

Ensure Stack is a clean, passable interface (not: separate admin from app access) #1

@cuibonobo

Description

@cuibonobo

The original framing of this issue proposed a new "admin vs. app" initialization API to prevent infrastructure concerns from leaking into app code. On reflection, the current design already handles this correctly — the concern is worth keeping but the proposed solution is the wrong fix.

What's already true

The "leak" in the current API is confined to two lines of bootstrap code:

const adapter = await SQLiteAdapter.initialize({ path, entityId, timezone });
const stack = await Stack.create(adapter);

After Stack.create(adapter), the app is fully adapter-agnostic. Creating records, querying, migrating, associating — none of that touches the adapter. The coupling is minimal and confined to one place, where it belongs: the entry point.

Why the proposed fix doesn't help

A URL-dispatch scheme like Stack.open('file://./my-stack.db') or Stack.open('https://...') doesn't eliminate the infrastructure concern — it relocates it. Auth tokens, connection options, and initialization-vs-open semantics don't flatten neatly into a URL string. Adding a new abstraction layer here would introduce its own edge cases without meaningfully reducing the app author's burden.

The goal — "an app written for local SQLite should work unmodified against a remote stack" — is already achievable. The only thing that changes between backends is the two lines of bootstrap code, and that code should change: choosing a backend is an infrastructure decision that belongs at the entry point, not buried in app logic. That's dependency injection by convention.

The real concern worth addressing

If the vision includes a plugin or extension model — third-party "app" code that receives a Stack it didn't create — then there's a legitimate need to ensure Stack is passable as an opaque handle without requiring the app to depend on any adapter package.

That's a TypeScript interface concern, not an initialization API concern. The actionable question is:

Does the public Stack type leak any adapter internals? If so, clean those up so Stack can be passed as a dependency without pulling in adapter-specific types.

That's likely a small, targeted change — and it directly addresses the use case without a new factory abstraction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions