Shared Modules Standard
Version: 1.0
Status: Approved
Owner: Platform Engineering
Last Updated: 2026-04-12
References: system.md §6, AGENT.md §2, §4
1. Purpose
This document defines the purpose, public API boundaries, versioning rules, and forbidden patterns for all packages in the packages/ workspace of the monorepo.
2. Package Inventory
| Package | Path | Purpose |
|---|---|---|
shared-types | packages/shared-types | TypeScript type definitions shared across services |
shared-utils | packages/shared-utils | Pure utility functions (HMAC, validation, SMPP PDU helpers) |
shared-config | packages/shared-config | Environment variable schemas and typed config loaders |
nats-client | packages/nats-client | Reusable NATS JetStream wrapper with durable consumer helpers |
db-client | packages/db-client | Prisma client wrapper with connection management |
logging | packages/logging | Pino logger factory + OpenTelemetry request tracing |
3. Package Descriptions and Public APIs
3.1 shared-types
Contains:
- Message types (
SmsMessage,DeliveryReceipt,MessageStatus) - Billing types (
BillingEvent,Invoice,PricingTier) - Operator types (
OperatorConfig,SmppBindConfig,RoutingRule) - API schemas (Zod schemas for request/response validation, re-exported as types)
- NATS message envelope types (
NatsEnvelope<T>)
Rules:
- MUST contain only type definitions and Zod schemas.
- MUST NOT contain business logic.
- MUST NOT import from any other package except standard TypeScript types.
3.2 shared-utils
Contains:
hmacSign(payload: string, secret: string): string— HMAC-SHA256 for webhook signinghmacVerify(payload: string, signature: string, secret: string): booleanvalidatePhoneNumber(phone: string): boolean— E.164 format validationgenerateIdempotencyKey(namespace: string, ...parts: string[]): stringsmppPduHelpers— PDU encoding/decoding utilities
Rules:
- All functions MUST be pure (no side effects, no I/O).
- MUST NOT import framework libraries (NestJS, Prisma, NATS).
- 90%+ unit test coverage required.
3.3 shared-config
Contains:
- Zod-based environment variable schemas per service
loadConfig<T>(schema: ZodSchema): T— validates env vars at startup, throws on missing required vars- Common config types (
DatabaseConfig,RedisConfig,NatsConfig)
Rules:
- Services MUST use this package to load config — no direct
process.envaccess in application/domain code. - Config MUST be validated at process startup, not lazily.
3.4 nats-client
Contains:
createNatsConnection(config: NatsConfig): NatsConnectioncreateJetStreamPublisher(conn, subject): PublishercreateDurableConsumer(conn, stream, subject, handler, options): Consumer- Retry policy wrappers (exponential backoff with jitter)
- Dead-letter queue routing helpers
Rules:
- All consumers MUST be durable — fire-and-forget is forbidden (AGENT.md §9.2).
- All messages MUST be acknowledged explicitly.
- DLQ routing MUST be configured for every consumer.
3.5 db-client
Contains:
createPrismaClient(config: DatabaseConfig): PrismaClient- Connection pooling configuration
- Transaction helpers
- Soft-delete utilities
Rules:
- Services MUST use this wrapper rather than instantiating
PrismaClientdirectly. - Connection strings MUST come from
shared-config. - MUST NOT expose raw SQL escape hatches.
3.6 logging
Contains:
createLogger(service: string, config: LogConfig): Logger— Pino logger factoryrequestTracingMiddleware— injectsx-trace-idandx-correlation-idinto all requests- OpenTelemetry span creation helpers
- Log level management by environment
Rules:
- All services MUST use this logger —
console.logis forbidden in production (AGENT.md §12.2). - Sensitive fields (passwords, API keys, phone numbers in plaintext) MUST be redacted before logging.
- Trace IDs MUST be propagated to all NATS messages and outbound HTTP calls.
4. Versioning
- Packages use semantic versioning (
MAJOR.MINOR.PATCH). - Breaking changes to a package's public API require a
MAJORversion bump and a migration guide. - All services pin to an exact version in
package.json(e.g."@ghasi/shared-types": "1.2.0"). - Within the monorepo, pnpm workspace protocol is used:
"@ghasi/shared-types": "workspace:*"during development.
5. Consumption Rules
- Services import from the package's index barrel (
@ghasi/shared-types) — never from internal paths. - Circular dependencies between packages are forbidden.
- A service package MUST NOT import from another service package — only from
packages/.
6. Forbidden Patterns
| Pattern | Reason |
|---|---|
| Business logic in shared packages | Violates service ownership boundaries |
Shared DB models in shared-types | Each service owns its own schema |
Direct process.env access in services | All config via shared-config |
console.log | Use logging package |
| Fire-and-forget NATS publish | Requires ack; use nats-client wrappers |
7. Assumptions and Open Points
| ID | Assumption / Open Point | Owner | Resolution Date |
|---|---|---|---|
| A-001 | Packages published to private npm registry or consumed via pnpm workspace only | Platform Eng | TBD |
| A-002 | shared-config Zod schemas per service to be defined during service scaffolding | Each service team | TBD |
| A-003 | OpenTelemetry SDK version to be pinned centrally in root package.json | Platform Eng | TBD |