Monorepo Layout
tripplan.ing uses npm workspaces to organize code across apps and shared packages. This page explains the structure, boundaries, and import rules.
Workspace structure
tripplan-ing/
├── apps/
│ ├── event-site/ # Main SvelteKit application
│ │ ├── src/
│ │ │ ├── hooks.server.ts
│ │ │ ├── lib/
│ │ │ │ ├── server/ # Server-only code (auth, DB, runtime, platform)
│ │ │ │ ├── components/
│ │ │ │ └── types.ts
│ │ │ └── routes/ # SvelteKit routes (admin, platform, api, public)
│ │ ├── drizzle/ # Generated migration files
│ │ ├── wrangler.toml # Cloudflare Worker config
│ │ └── package.json
│ └── docs/ # VitePress documentation site
│ ├── .vitepress/config.ts
│ └── **/*.md
├── packages/
│ ├── platform-shared/ # Platform contracts, validation, lifecycle rules
│ │ ├── src/
│ │ │ ├── event-lifecycle.ts
│ │ │ └── validation.ts
│ │ └── package.json
│ ├── runtime-core/ # Shared runtime primitives (KV interface, env helpers)
│ │ ├── src/
│ │ │ └── kv.ts
│ │ └── package.json
│ └── ui/ # Shared UI components (if any)
│ └── package.json
├── scripts/ # Repository-level scripts
├── .github/workflows/ # CI/CD pipelines
├── Makefile # Convenience commands
└── package.json # Root workspace configPackage roles
apps/event-site
The main application. Contains all business logic, routes, database schema, and runtime implementations. This is where most development happens.
packages/platform-shared
Cross-cutting platform contracts that are shared between the app and any future consumers:
- Event lifecycle: State machine rules (
isLifecycleReadOnly(), valid transitions) - Validation: Email normalization, input sanitization
Import as:
import { isLifecycleReadOnly } from '@tripplan/platform-shared/event-lifecycle';
import { normalizeEmail } from '@tripplan/platform-shared/validation';packages/runtime-core
Shared runtime primitives — interfaces that both runtimes (Cloudflare and Node) implement:
- KV interface:
KvStoretype withget,put,deletemethods
Import as:
import type { KvStore } from '@tripplan/runtime-core/kv';packages/ui
Shared UI components (Svelte). Currently minimal.
Boundary rules
What goes where
| Code type | Location |
|---|---|
| Event business logic | apps/event-site/src/lib/server/ |
| Platform management logic | apps/event-site/src/lib/server/platform/ |
| Database schema | apps/event-site/src/lib/server/db/schema.ts |
| Runtime abstraction | apps/event-site/src/lib/server/runtime/ |
| Shared interfaces (KV, etc.) | packages/runtime-core/ |
| Lifecycle rules, validation | packages/platform-shared/ |
| UI components | apps/event-site/src/lib/components/ or packages/ui/ |
Import rules
- Apps can import packages:
apps/event-sitecan import from@tripplan/platform-sharedand@tripplan/runtime-core - Packages cannot import apps: Shared packages must not depend on app code
- Packages can import other packages:
platform-sharedcan import fromruntime-coreif needed - Use package names for cross-workspace imports: Always
@tripplan/platform-shared/..., never relative paths across workspace boundaries
Enforcing boundaries
Run the boundary checker to validate import rules:
npm run check:boundariesThis checks that:
- Shared packages don't import from
apps/ - Cross-workspace imports use package names
- No circular dependencies between packages
Adding shared code
Before adding code to a shared package, verify it meets the criteria:
platform-shared: Must be a platform contract, lifecycle rule, or validation utility. No runtime-specific code.runtime-core: Must be an interface or primitive used by both runtimes. No implementation code.
If the code is only used by apps/event-site, keep it in apps/event-site/src/lib/. Don't prematurely extract to packages.
Build and CI
The CI workflow (.github/workflows/apps-ci.yml) handles:
- Install:
npm ciat root (installs all workspaces) - Check:
npm run check(TypeScript + Svelte + boundary checks) - Test:
npm test - Build:
npm run build(builds the Worker) - Deploy: Wrangler deploy with migration and secret sync
Docs have a separate workflow (.github/workflows/docs-deploy.yml).
Related pages
- Architecture — how modules connect at runtime
- Commands — build, check, and deploy commands
- CI/CD Pipeline — deployment workflow details