Workspace Dependency Graph
Arrows point from the importer to the thing it imports. shared/ is leaf code: everything points into it, nothing points out of it. That direction is enforced mechanically by tools/lint/check-shared-boundaries.ts (see ADR 0006).
graph LR
subgraph Consumers["Consumer packages"]
FE["frontend/<br/>(Angular 21)"]
FN["functions/<br/>(Cloud Functions)"]
TB["tools/build<br/>(content pipeline)"]
BS["tools/blog-scheduler<br/>(CLI, standalone)"]
end
subgraph Shared["shared/ — leaf code"]
SM["@jjk/models"]
SC["@jjk/constants"]
SU["@jjk/utils<br/>(no current consumers)"]
SS["@jjk/services<br/>(empty barrel)"]
end
FE --> SM
FE --> SC
FE -.-> SU
FN --> SC
TB --> SM
classDef idle fill:#f4f4f4,stroke:#999,color:#666,stroke-dasharray: 4 2
class SU,SS,BS idle
Current package responsibilities
| Package | Role | Imports from shared/ |
|---|---|---|
frontend/ |
Angular 21 blog app, admin dashboards, prerendered at build time | @jjk/models, @jjk/constants |
functions/ |
Firebase Cloud Functions — callable handlers, Firestore triggers, third-party integrations | @jjk/constants |
tools/build |
Markdown → JSON content pipeline (Shiki, Mermaid, route manifest, search index) | @jjk/models |
tools/blog-scheduler |
Mon/Thu publication slot CLI | none |
What the graph enforces
- Direction.
shared/is a dependency sink. No arrow flows out of theshared/subgraph. Attempting to add one — ashared/file importing@app/*, or a relative path that escapesshared/, or a barefrontend/functions/toolsspecifier — failsnpm run buildvia the boundary check. - Independence.
tools/blog-scheduleris a standalone CLI with no shared-code dependencies. It can be extracted to its own repo without touching anything else. - Runtime vs. build-time. This graph shows TypeScript import dependencies only.
tools/buildalso producesfrontend/src/assets/generated/**as a build artifact consumed by the prerendered frontend — that relationship is captured in the content pipeline diagram, not here.
What this graph does not show
functions/is not an npm workspace member (it has its ownnode_modulesand deploys independently). It resolves@jjk/constantsvia a localtsconfig.jsonpathsmap.- Third-party dependencies (Firebase SDKs, Angular, Shiki, Mermaid, Sentry, Resend, LinkedIn API) are omitted for readability. They are consumed by the Consumer packages, never by
shared/except for pure types.