Skip to content

Development & Testing Workflow

Kryptofolio is organized as a PNPM Workspaces Monorepo powered by Turborepo for caching, pipeline orchestration, and task execution.


The repository is structured to strictly decouple domain rules from infrastructure and presentation:

kryptofolio/
├── apps/
│ ├── frontend/ # Vue 3 UI, Pinia stores/Colada, TailwindCSS v4, shadcn-vue
│ └── backend/ # Hono.js API server, Vault, DuckDB orchestrator, jobs
└── packages/
├── core-domain/ # Pure business logic (Services, Normalizers, Value Objects)
├── shared-types/ # Shared TypeScript types, Zod DTO schemas, RPC contracts
└── database/ # SQLite migrations, DuckDB SQL views, database adapters
  1. core-domain has zero external framework dependencies (no Vue, no Hono, no Axios, no SQL drivers).
  2. shared-types only depends on zod for Data Transfer Object (DTO) schema enforcement.
  3. frontend never directly imports backend implementations or database packages. All communication happens via Hono RPC (hc<AppType>).

Turborepo caches build and test artifacts in .turbo/. Common workspace tasks:

Command Action Concurrency Note
pnpm dev:full Launches frontend and backend concurrently Long-running dev servers
pnpm build Compiles all packages (turbo run build) Respects topological ^build order
pnpm test Runs Vitest suites (turbo run test --concurrency=1) Capped at 1 to prevent DuckDB thread starvation
pnpm typecheck Executes vue-tsc and TypeScript typechecks Static compilation verification
pnpm lint Runs ESLint across all workspace directories Style and lint enforcement

[!WARNING] Why --concurrency=1 for testing? DuckDB creates native worker threads during analytical queries. Running multiple package test suites in parallel over file-backed instances can cause CPU thread starvation, which DuckDB surfaces as an unexpected query timeout. Running packages sequentially guarantees deterministic test runs.


Quality control follows strict Test-Driven Development (TDD) principles:

  • Unit Testing Pure Domain: packages/core-domain tests focus on normalizers, ingestion pipelines, and FIFO event calculations with 100% deterministic test vectors.
  • Integration Testing Adapters: packages/database and apps/backend test real SQLite transactions and DuckDB Window Functions against memory databases (:memory: or temporary test files).
  • Zero any Policy: Production code must compile with vue-tsc --noEmit without a single any bypass.

🔖 Versioning & Releases (“Frontend is King”)

Section titled “🔖 Versioning & Releases (“Frontend is King”)”

Kryptofolio uses Changesets for automated package versioning and changelog generation.

  • Even though packages are versioned independently, the version of @kryptofolio/frontend represents the de facto user-facing application version.
  • Prefer patch version bumps during early development stages to keep semantic version increments measured and deliberate.

Before opening a pull request that modifies package code:

Terminal window
pnpm changeset
  1. Select the packages affected by your changes.
  2. Choose the bump type (patch, minor, major).
  3. Enter a concise markdown summary of the change.
  4. Commit the generated .changeset/*.md file.

When merged to main, the GitHub Actions CD pipeline will automatically bump versions, update CHANGELOG.md, and publish releases.