Contributor guide
This repository is an npm-workspace monorepo for the API, admin console, reusable clients, components, and demonstration applications.
Set up
git clone https://github.com/adubbs/activities.git
cd activities
npm install
npm run dev:dependencies
cp apps/api/.env.example apps/api/.env
npm run seed:scenario
npm run devUse the Node version in .nvmrc. Change the copied development key to a local value of at least 16 characters and use the same value in the admin console.
Repository map
| Path | Responsibility |
|---|---|
apps/api | Hapi modular monolith, worker, scripts, and AVA tests |
apps/web-admin | Vue 3 + Vite developer console and Vitest tests |
packages/sdk-core | Framework-independent TypeScript HTTP client and contracts |
packages/websocket-client | Framework-independent realtime client |
packages/vue-components | Drop-in Vue feed, calendar, and Markdown components |
demos | Nuxt applications using public data and supported clients |
infra | Local MongoDB replica set and OpenSearch |
docs | This VitePress site, ADRs, milestone records, and assumptions |
activity_platform_kickoff | Original product/architecture brief |
Check for a more specific AGENTS.md before changing a subtree. In particular, apps/api contains service-specific working guidance.
Development loop
- Start dependencies with
npm run dev:dependencies. - Start the app with
npm run dev. - Add or update the smallest relevant tests while changing behavior.
- Exercise the consumer path in the admin console or a demo.
- Run focused workspace checks.
- Run
npm run verifybefore handing off a broad change.
The root dev command starts API, worker, and web processes. If you change SDK contracts while the app is running, use npm run dev:packages or rebuild the affected package.
Product and contract rules
- Events are immutable; fixes are new facts or rebuildable projection changes.
- Idempotency belongs at ingestion boundaries.
- Organization, environment, and visibility scope must be applied before pagination or aggregation.
- Cursors are opaque public contracts.
- MongoDB is authoritative; OpenSearch and feed projections must be rebuildable or idempotent.
- Consumers receive deterministic feed contracts, not MongoDB query details.
- Realtime messages complement durable REST state and must survive reconnect reasoning.
- Shared packages remain framework-independent unless the package is explicitly framework-specific.
Make a change
Keep feature modules vertical inside apps/api/src/<feature>: route schemas, controller, domain service, and repository/model code should live together. Wire modules through the server composition root rather than cross-importing transport details.
When a public endpoint changes, update:
- Joi request and response schemas;
- controller/service behavior;
- SDK types and client method where applicable;
- focused tests;
- Swagger examples or descriptions;
- consumer documentation in this site.
When an event changes consumer rendering, test both raw-event acceptance and the resulting activity, including rollups, links, visibility, and source-event provenance.
Pull request checklist
- The change has a clear consumer outcome.
- Tests cover success, validation, tenant/visibility isolation, and idempotent retries where relevant.
- New configuration is validated and added to
.env.exampleand the configuration docs. - Public types and examples match the running Swagger contract.
- Migration, backfill, reindex, or compatibility needs are documented.
npm run verifyandnpm run docs:buildpass.