Skip to content

Feature Slice Workflow

Use this page when a change crosses more than one local file or one app boundary. It distills the working pattern that has emerged from auth, artist media, relationship management, query controls, reusable component localization, deployed smoke testing, and docs graduation work.

The goal is not to force every feature through a heavyweight checklist. The goal is to choose the right owning boundary early, keep each change inspectable, and leave future contributors with a clearer system than the one you found.

Before writing code, identify the smallest surface that owns the behavior:

Change ShapeLikely Owner
Page-only layout, state, or copyapps/wavemap-front-end
Backend route behaviorapps/wavemap-back-end
Shared route, DTO, envelope, or codepackages/api-contracts
Locale, namespace, email, or labelspackages/i18n
Generic constants or helperspackages/shared-utils
Public command routepackages/cli
Operational planning or projectioninfra/operations
Cloud resource or output contractinfra/pulumi
Stable explanation or runbookapps/wavemap-docs/src/content/docs
Active planning or branch scratchapps/wavemap-docs/working-notes or an app-local roadmap

Keep the first pass narrow. If the change would add dependencies, reshape build tooling, modify CI/CD, change infrastructure, introduce a new cross-package API, or refactor across unrelated areas, pause and write a plan first.

When frontend and backend behavior meet, prefer a shared contract before app-specific wiring.

Use @wavemap/api-contracts for:

  • API route constants.
  • Frontend route constants that need shared identity.
  • Request and response DTOs.
  • API envelopes and error identity.
  • Role and permission codes.
  • Query controls, filtering, sorting, pagination, and endpoint capabilities.
  • Domain code arrays that need backend seeds or i18n verification.

Then wire the owning apps:

  1. Add or update the shared contract.
  2. Implement backend parsing, validation, handler behavior, and response shape.
  3. Implement frontend API functions, hooks, page workflow state, and UI presentation.
  4. Add localized copy and reusable component label maps where visible text crosses a component boundary.
  5. Add targeted tests at the contract, route, hook, page, or browser layer that owns the risk.

Do not duplicate route strings, DTO shapes, permission codes, or query-control criteria in app code when a shared contract already exists.

Backend changes should keep transport, domain behavior, and infrastructure concerns separate.

For route work:

  • Keep request validation near the route or handler boundary.
  • Return shared API envelopes and DTO-compatible response shapes.
  • Preserve fallback message text when adding localized messageKey and messageInterpolationValues.
  • Keep logs, operator diagnostics, and raw third-party failure details out of user-facing localized errors.
  • Use development-only response validation where the nearby route family already uses it.

For database-backed work:

  • Keep business uniqueness separate from row identity on association rows.
  • Use explicit query builders for entity-specific filtering, sorting, aggregate counts, and stable fallback ordering.
  • Prefer page-ready summary DTOs for browsing pages instead of full nested graphs.
  • Add DB-backed tests when SQL shape, aggregate behavior, pagination totals, or relationship state matters.

For media work:

  • Keep entity detail routes JSON-focused.
  • Route media uploads, sync, deletes, ingest, and storage behavior through media-specific backend workflows.
  • Persist provider-agnostic storage locators, not provider-shaped URLs as canonical identity.
  • Treat LocalStack and Azurite as execution targets, not persisted providers.

Frontend changes should separate generic UI, page/domain orchestration, and transport details.

Reusable components should own generic interaction behavior:

  • Input, popover, table, sheet, carousel, upload, pagination, and selection mechanics.
  • Accessibility behavior and default display text where reuse outside Wavemap is useful.
  • Grouped labels props when internal visible copy spans several subcomponents.

Page or domain wrappers should own product context:

  • API hook invocation.
  • DTO mapping.
  • Query state and URL serialization.
  • Saved-view behavior.
  • Workflow sequencing and retry posture.
  • Localized copy and formatter functions.

For queryable pages:

  • Derive available controls from endpoint capabilities.
  • Normalize draft query state into API query groups at the apply boundary.
  • Reset pagination when search, page size, filters, or sorts change the dataset.
  • Keep URL state reloadable and saved views durable by page and schema version.

Treat visible copy as part of the feature contract.

Use @wavemap/i18n when adding or changing:

  • Locale sheets.
  • Namespaces.
  • Code-driven display values.
  • Backend user-facing errors.
  • Automated email copy.
  • Reusable component label maps.
  • Generated i18n assets or CDN-facing delivery behavior.

Prefer these rules:

  • Namespace filenames and namespace constants must match exactly.
  • Translation sheets should mirror English key paths, value shapes, ICU values, and _meta structure.
  • Backend errors use server--errors only when the backend must produce user-facing text.
  • Automated emails use dedicated email--* namespaces and backend-side copy adapters.
  • Reusable Wavemap surfaces should pass display-ready text, not translation keys, into generic components.

Run pnpm format:i18n and pnpm verify:i18n when translation resources or i18n contracts change.

Cloud, deployment, CI/CD, and operational command changes need explicit boundaries.

Use the public CLI route when documenting commands:

Terminal window
pnpm wavemap -- ...

Keep implementation ownership split:

  • packages/cli owns the public command surface and route-contract tests.
  • Shell wrappers own live execution, provider CLIs, wait loops, --execute gates, and operator process control.
  • infra/operations owns typed parsing, planning, validation, summaries, projections, and helper outputs.
  • infra/pulumi owns cloud resources, IAM, DNS, runtime host shape, docs hosting, and output contracts.

Before presenting automation as ready to run, trace the cloud API actions, target resources, IAM permissions, trust policy needs, and existing IaC or workflow surfaces. Live cloud mutation, permission changes, deploy runs, destructive operations, and commits remain explicit human gates. Use Cloud Automation Permission Review for the durable review checklist.

Choose the cheapest layer that proves the behavior.

RiskUseful Proof
DTO or contract shapeAPI contract tests or route validation tests.
Backend parsing or handler behaviorMocked request tests.
SQL, aggregates, joins, or persistenceDB-backed integration tests.
Frontend API serialization or query keyAPI utility and hook tests.
Component prop surface or interactionVitest component tests.
Page workflow statePage integration tests.
Browser-only routing or focus behaviorNarrow Playwright smoke.
Deployed runtime or cloud integrationProfile-scoped deployed smoke and operator-reviewed artifacts.
Script, CLI, or generated artifactManifest-backed contract tests and targeted operations tests.

Avoid making broad E2E coverage the first proof for a feature unless the bug only exists in a browser or deployed runtime. Keep smoke lanes small, explicit, and cheap enough to interpret.

Keep scratch material close to the work while the shape is moving:

  • App-local notes for feature-specific implementation history.
  • apps/wavemap-docs/working-notes for planning, proof history, and unsettled follow-ups.
  • Roadmaps for active sequencing and branch-level decisions.

Promote material into the docs site when it becomes useful stable reference:

  • Architecture pages for durable system boundaries.
  • Developer pages for package, app, testing, CLI, and contribution patterns.
  • Operations pages for reviewed procedures, recovery paths, deployment workflows, and approval gates.
  • Admin pages only when the content model or CMS-facing workflow is stable enough for non-platform readers.

After graduation, trim the roadmap or working note so there is one durable reference and one live planning surface, not two competing explanations.

Before calling a feature slice ready, check:

  • The owning boundary is clear.
  • Shared contracts live in the shared package instead of being copied between apps.
  • Backend and frontend error/display behavior agree on API envelopes and localization identity.
  • Reusable components receive display-ready labels or formatter functions instead of Wavemap translation keys.
  • Tests cover the narrowest layer that proves the risk.
  • Runtime config, secrets, deploy values, and cloud permissions are documented at the right audience layer.
  • Working notes keep branch history, while stable lessons are linked from curated docs.