Skip to content

Project Structure

Ferran Buireu edited this page Jun 13, 2026 · 2 revisions

Project Structure

ContribKit is a pnpm-workspace monorepo with three components that share design tokens.

ContribKit/
├── web/        Astro + TypeScript on Cloudflare Workers (contribkit.app + API)
├── app/        Flutter iOS & Android app with home-screen widgets
├── shared/     Single source of truth: palettes, shapes, usernames (JSON)
├── scripts/    Repo tooling (e.g. sync-shared-assets.mjs)
└── .github/    CI/CD workflows
Directory Component Stack
web/ contribkit.app + SVG/JSON API Astro · TypeScript · Cloudflare Workers
app/ iOS & Android app with widgets Flutter · Riverpod · RevenueCat
shared/ Palettes, shapes, usernames JSON consumed by both apps

web/src

domain/          Pure business core (value objects, entities, services, failures)
application/     Curried use cases + Failure → HTTP mapping
infrastructure/  GitHub scraping, SVG renderer, logging
ui/              Astro components, client utils, styles
pages/           Routes + API endpoints (the composition root)

See Architecture for the role of each layer and Web Application for tooling.


app/lib

domain/          Entities, value objects, repository interfaces, services, failures
application/     Use cases (fetch, export, tips)
infrastructure/  GitHub repo, asset repos, export (png/svg/markdown), persistence, purchases
ui/              Features (viewer, customizer, export, tip), widgets, theme, DI

See Mobile App.


shared/ — design tokens

The single source of truth for data used by both apps:

File Contents
palettes.json 11 color palettes (5 levels each)
shapes.json 5 cell shapes
usernames.json Suggested usernames

Edit the JSON here — never edit the copies under app/assets/.

  • web imports these directly via the @shared alias at build time.
  • app (Flutter) can only bundle assets inside its own package, so it uses generated copies in app/assets/*.json. They are regenerated:
    • automatically on commit (lefthook pre-commit runs scripts/sync-shared-assets.mjs --stage when a shared/*.json is staged),
    • in CI before the release build,
    • manually with pnpm sync:assets.

Monorepo tooling

  • Package manager: pnpm workspaces (pnpm-workspace.yaml)
  • Git hooks: lefthook (lefthook install)
  • Commits: Conventional Commits, enforced by commitlint
  • Releases: semantic-release per component (web-vX.Y.Z / app-vX.Y.Z tags)
  • CI: path-filtered workflows that only run when their component changes — see CI/CD

Clone this wiki locally