Skip to content

refactor: Gradual const & type convention alignment #643

Description

@jirispilka

Context and motivation

The codebase has accumulated deviations from our target const/type conventions:

  • Same-file first, feature-folder second, root shared only for cross-cutting symbols
  • type over interface
  • as const objects over TypeScript enum
  • enumeration as const objects and their same-named type in uppercase SNAKE_CASE

Current state:

  • src/const.ts (217 lines, 50+ exports) mixes unrelated domains — cache config, Skyfire payment strings, telemetry params, actor limits — many used by only 1–2 files
  • src/types.ts (698 lines, 47 exports) contains 3 dead exports, 6 single-consumer types, and pricing types only used in src/utils/pricing_info.ts
  • src/web/src/types.ts uses interface where type is the convention
  • HelperTools is a TypeScript enum (123 imports across 35+ files) — convention says as const
  • ServerMode (src/types.ts) is already an as const object but is PascalCase — the enumeration convention wants uppercase SNAKE_CASE (SERVER_MODE)

Scope

In scope

  • Remove dead/unused exports from src/types.ts and src/const.ts
  • Move single-consumer constants from root src/const.ts to their consuming files
  • Move single-consumer types from root src/types.ts to their consuming files
  • Move Skyfire constants to src/payments/const.ts
  • Convert interface to type in src/web/src/types.ts
  • Convert HelperTools enum to as const object
  • Rename the ServerMode enumeration object + type to SERVER_MODE (SNAKE_CASE)

Out of scope

  • Broad mechanical rewrites of existing code
  • Moving cross-cutting types/constants that are genuinely shared (10+ consumers)
  • Refactoring src/types.ts types that have complex dependency chains (e.g., ActorDefinitionWithDesc — used by ActorDefinitionPruned via Pick<>)
  • Changes to src/payments/types.ts (already well-organized)

Phased plan

Each phase is an independent PR. Phases 1, 2, 5 can run in parallel.

Phase 1 (dead code) ─┬─→ Phase 3 (localize types)
                      └─→ Phase 4 (Skyfire constants)
Phase 2 (localize consts)     (independent)
Phase 5 (interface→type)      (independent)
Phase 6 (HelperTools enum)    (after Phases 1–4)
Phase 7 (ServerMode naming)   (independent)

Sub-issues


Phase 1: Remove dead exports

File Change
src/types.ts Un-export PricingTier and TieredEventPrice — inline into ActorChargeEvent field type
src/const.ts Remove export from SKYFIRE_MIN_CHARGE_USD and SKYFIRE_SELLER_ID (0 external imports)

Phase 2: Localize single-consumer constants

Move constants from src/const.ts to their sole consumer:

Constant(s) Move to
ACTOR_CACHE_MAX_SIZE, ACTOR_CACHE_TTL_SECS, APIFY_DOCS_CACHE_MAX_SIZE, APIFY_DOCS_CACHE_TTL_SECS, MCP_SERVER_CACHE_MAX_SIZE, MCP_SERVER_CACHE_TTL_SECS src/state.ts
USER_CACHE_MAX_SIZE, USER_CACHE_TTL_SECS src/utils/userid_cache.ts
MCP_STREAMABLE_ENDPOINT src/mcp/const.ts
ACTOR_SEARCH_ABOVE_LIMIT src/utils/actor_search.ts
PROGRESS_NOTIFICATION_INTERVAL_MS src/utils/progress.ts
USER_AGENT_ORIGIN src/apify_client.ts
SEGMENT_FLUSH_AT_EVENTS, SEGMENT_FLUSH_INTERVAL_MS src/telemetry.ts

Phase 3: Localize single-consumer types

Type Move to Notes
ActorInputSchemaProperties src/tools/utils.ts Trivial alias, used only there
ActorChargeEvent src/utils/pricing_info.ts Only production consumer
ActorPricingModel src/utils/actor_search.ts Derived type, used only there
TieredPricing, PricingInfo, PricePerEventActorPricingInfo src/utils/pricing_info.ts Pricing type cluster

Update src/utils/actor_card.ts to import PricingInfo from ./pricing_info.js.

Note: ActorDefinitionWithDesc stays — ActorDefinitionPruned depends on it via Pick<>.


Phase 4: Move Skyfire constants to src/payments/

Create src/payments/const.ts with:

  • SKYFIRE_MIN_CHARGE_USD, SKYFIRE_SELLER_ID, SKYFIRE_TOOL_INSTRUCTIONS, SKYFIRE_PAY_ID_PROPERTY_DESCRIPTION, SKYFIRE_README_CONTENT, SKYFIRE_ENABLED_TOOLS

Move CALL_ACTOR_MCP_MISSING_TOOL_NAME_MSGsrc/tools/core/call_actor_common.ts (only consumer).


Phase 5: Convert interface to type in web UI

src/web/src/types.ts: Change interface ActorStats, interface ActorDetails, interface Actor to type.

Keep declare global { interface Window { ... } } (correct use of interface).


Phase 6: Convert HelperTools enum to as const

6a (additive): Add HELPER_TOOLS as const object + HelperToolName type alongside existing enum. Re-export both from index_internals.ts.

6b (migration): Replace HelperTools.XHELPER_TOOLS.X across 40+ files. Update CONTRIBUTING.md and CLAUDE.md.

6c (cleanup): Remove enum HelperTools. Keep backwards-compat alias in index_internals.ts if internal repo needs migration time.

Also convert local TransportType/Routes enums in src/dev_server.ts. (dropped — those enums no longer exist)

Delivered in PR #1043: enum removed; migrated ~460 refs across 52 files; kept a @deprecated HelperTools value+type alias in index_internals.ts, so the internal repo needs no changes (backward compatible).


Phase 7: Rename ServerModeSERVER_MODE

Found during Phase 6. ServerMode in src/types.ts is already an as const object + same-named type, but PascalCase — the enumeration convention (CONTRIBUTING.md) wants uppercase SNAKE_CASE. Rename the object and its type to SERVER_MODE (keys DEFAULT/APPS and values 'default'/'apps' unchanged). ~140 references (80 src + 60 tests). Not exported via index_internals.ts, and the internal repo has its own ServerMode, so no cross-repo coordination needed. Bundled into PR #1043.

Internal repo impact

  • Phases 1–5, 7: No impact.
  • Phase 6: HelperTools is exported via index_internals.ts. Shipped with a @deprecated HelperTools alias, so the internal repo keeps compiling unchanged.

Verification checklist (every phase)

  • npm run type-check passes
  • npm run lint passes
  • npm run test:unit passes
  • Internal repo impact assessed
  • No breaking changes (or coordinated)

Open questions

  • Phase 6: coordinate with internal repo upfront, or use deprecation alias approach? Resolved: deprecation alias (backward compatible), internal repo untouched.

Metadata

Metadata

Assignees

No one assigned

    Labels

    t-aiIssues owned by the AI team.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions