@voltom/contracts 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,486 @@
1
+ # @voltom/contracts
2
+
3
+ Universal contract language for voltom products — primitive types, response shapes, error codes, and the `defineContract()` engine.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - **Node.js** 20+ ([download](https://nodejs.org))
10
+ - **npm** 10+ (included with Node.js)
11
+ - **Git** (for cloning and versioning)
12
+
13
+ ### Installation & Setup
14
+
15
+ ```bash
16
+ # 1. Navigate to the project
17
+ cd /Users/jzegarram/product-factory/@voltom-contracts
18
+
19
+ # 2. Install dependencies
20
+ npm install
21
+
22
+ # 3. Verify everything works
23
+ npm run test
24
+
25
+ # 4. Start developing
26
+ npm run dev
27
+ ```
28
+
29
+ ### Development Workflow
30
+
31
+ #### Watch Mode (Recommended for development)
32
+
33
+ ```bash
34
+ npm run dev
35
+ ```
36
+
37
+ This runs TypeScript compiler in watch mode. Any changes to `src/` files trigger a rebuild automatically.
38
+
39
+ #### Run Tests
40
+
41
+ ```bash
42
+ # Run tests once
43
+ npm run test
44
+
45
+ # Run tests in watch mode (re-run on file changes)
46
+ npm run test:watch
47
+ ```
48
+
49
+ #### Type Checking
50
+
51
+ ```bash
52
+ # Check TypeScript without emitting
53
+ npm run type-check
54
+ ```
55
+
56
+ Run this before committing to catch type errors early.
57
+
58
+ #### Build for Production
59
+
60
+ ```bash
61
+ # Create dist/ with CJS, ESM, and .d.ts
62
+ npm run build
63
+ ```
64
+
65
+ Output:
66
+ - `dist/index.js` — CommonJS (Node.js)
67
+ - `dist/index.mjs` — ES Modules (browsers, modern tools)
68
+ - `dist/index.d.ts` — TypeScript declarations
69
+
70
+ ### Project Structure
71
+
72
+ ```
73
+ src/
74
+ ├── primitives.ts ← t.* type builders (add new types here)
75
+ ├── responses.ts ← Response envelopes (SingleResponse, etc.)
76
+ ├── errors.ts ← ErrorCode + HTTP status map
77
+ ├── contract.ts ← defineContract() engine
78
+ ├── helpers.ts ← Production patterns (auditFields, etc.)
79
+ ├── index.ts ← Public API exports
80
+ └── types/
81
+ ├── contract.types.ts
82
+ └── pagination.types.ts
83
+ __tests__/
84
+ └── primitives.test.ts ← Test examples
85
+ ```
86
+
87
+ ### Common Development Tasks
88
+
89
+ #### Add a New Primitive Type
90
+
91
+ 1. **Define in `src/primitives.ts`**:
92
+ ```typescript
93
+ export const t = {
94
+ // ... existing types ...
95
+ myNewType: (opts?: { /* options */ }) => {
96
+ // Use Zod under the hood
97
+ return z.string().custom(/* validation */)
98
+ }
99
+ }
100
+ ```
101
+
102
+ 2. **Add tests to `src/__tests__/primitives.test.ts`**:
103
+ ```typescript
104
+ describe('t.myNewType()', () => {
105
+ it('validates correct input', () => {
106
+ const schema = t.myNewType()
107
+ expect(schema.parse('valid-input')).toBe('valid-input')
108
+ })
109
+
110
+ it('rejects invalid input', () => {
111
+ const schema = t.myNewType()
112
+ expect(() => schema.parse('invalid')).toThrow()
113
+ })
114
+ })
115
+ ```
116
+
117
+ 3. **Verify tests pass**:
118
+ ```bash
119
+ npm run test
120
+ ```
121
+
122
+ 4. **Update `src/index.ts` if needed** (usually auto-exported from primitives)
123
+
124
+ 5. **Create a changeset**:
125
+ ```bash
126
+ npx changeset
127
+ # Select: patch (bug fix), minor (new type), or major (breaking change)
128
+ ```
129
+
130
+ #### Add a New Error Code
131
+
132
+ 1. **Update `src/errors.ts`**:
133
+ ```typescript
134
+ export type ErrorCode =
135
+ | 'EXISTING_ERROR'
136
+ | 'MY_NEW_ERROR' // ← Add here
137
+
138
+ export const ERROR_STATUS_MAP: Record<ErrorCode, number> = {
139
+ EXISTING_ERROR: 400,
140
+ MY_NEW_ERROR: 409, // ← Add HTTP status
141
+ }
142
+
143
+ export const ERROR_MESSAGES: Record<ErrorCode, string> = {
144
+ EXISTING_ERROR: 'Error message',
145
+ MY_NEW_ERROR: 'My error message', // ← Add default message
146
+ }
147
+ ```
148
+
149
+ 2. **Test it**:
150
+ ```bash
151
+ npm run type-check
152
+ npm run test
153
+ ```
154
+
155
+ 3. **Create a changeset** (⚠️ This is a breaking change):
156
+ ```bash
157
+ npx changeset
158
+ # Select: major (breaking change — all products must update)
159
+ ```
160
+
161
+ #### Update Response Shapes
162
+
163
+ **⚠️ WARNING:** Response shapes are locked. Changes require major version bump and coordination with all products.
164
+
165
+ Do NOT change existing fields. If you need a new response type:
166
+
167
+ 1. **Create new envelope in `src/responses.ts`**
168
+ 2. **Export from `src/index.ts`**
169
+ 3. **Document in README**
170
+ 4. **Changeset as major version**
171
+ 5. **Notify all products**
172
+
173
+ ---
174
+
175
+ ## Before You Commit
176
+
177
+ Run this checklist:
178
+
179
+ ```bash
180
+ # 1. Format & lint (if you add linting rules)
181
+ npm run lint
182
+
183
+ # 2. Type check
184
+ npm run type-check
185
+
186
+ # 3. Run all tests
187
+ npm run test
188
+
189
+ # 4. Build
190
+ npm run build
191
+
192
+ # 5. Verify bundle size
193
+ ls -lh dist/
194
+ ```
195
+
196
+ If all pass, you're ready to commit.
197
+
198
+ ---
199
+
200
+ ## Publishing to npm
201
+
202
+ ### Step-by-Step
203
+
204
+ ```bash
205
+ # 1. Make your changes
206
+ # (edit src/primitives.ts, src/errors.ts, etc.)
207
+
208
+ # 2. Write tests for new types
209
+ # (edit src/__tests__/primitives.test.ts)
210
+
211
+ # 3. Verify everything locally
212
+ npm run test
213
+ npm run type-check
214
+ npm run build
215
+
216
+ # 4. Create a changeset
217
+ npx changeset
218
+ # Follow the prompts:
219
+ # - Select type: patch | minor | major
220
+ # - Write summary of changes
221
+ # - Describe why in more detail
222
+
223
+ # 5. Commit your changes
224
+ git add .
225
+ git commit -m "feat: add new type or error code"
226
+
227
+ # 6. Push to GitHub
228
+ git push origin your-branch
229
+
230
+ # 7. Create PR, get reviewed, merge to main
231
+ # (CI automatically publishes on merge)
232
+ ```
233
+
234
+ ### CI/CD (Automatic on Merge)
235
+
236
+ When you merge to `main`, GitHub Actions automatically:
237
+
238
+ 1. ✅ Runs all tests
239
+ 2. ✅ Builds the package
240
+ 3. ✅ Bumps version (`package.json`, `CHANGELOG.md`)
241
+ 4. ✅ Publishes to GitHub Packages
242
+
243
+ You don't need to do anything else.
244
+
245
+ ---
246
+
247
+ ## Troubleshooting
248
+
249
+ ### Tests Failing
250
+
251
+ ```bash
252
+ # Clear node_modules and reinstall
253
+ rm -rf node_modules package-lock.json
254
+ npm install
255
+ npm run test
256
+ ```
257
+
258
+ ### Type Errors
259
+
260
+ ```bash
261
+ # Run type checker for detailed errors
262
+ npm run type-check
263
+
264
+ # Fix TypeScript errors in the code
265
+ # (usually in src/ files)
266
+
267
+ # Re-run type-check
268
+ npm run type-check
269
+ ```
270
+
271
+ ### Build Failing
272
+
273
+ ```bash
274
+ # Check tsup config
275
+ cat tsup.config.ts
276
+
277
+ # Try rebuilding with clean slate
278
+ npm run build
279
+
280
+ # Check dist/ was created
281
+ ls dist/
282
+ ```
283
+
284
+ ### Changeset Issues
285
+
286
+ ```bash
287
+ # If you haven't created a changeset
288
+ npx changeset
289
+
290
+ # If changeset is malformed, fix it
291
+ # (changesets are in .changeset/*.md files)
292
+
293
+ # Verify changeset is valid
294
+ cat .changeset/*.md
295
+ ```
296
+
297
+ ---
298
+
299
+ ## File Reference
300
+
301
+ | File | Purpose | When to edit |
302
+ |------|---------|--------------|
303
+ | `src/primitives.ts` | Type builders | Adding new `t.*` types |
304
+ | `src/responses.ts` | Response envelopes | (Locked — don't edit) |
305
+ | `src/errors.ts` | Error codes | Adding new ErrorCode |
306
+ | `src/helpers.ts` | Production patterns | Adding new helpers |
307
+ | `src/index.ts` | Public API | Exporting new code |
308
+ | `src/__tests__/primitives.test.ts` | Tests | Every new type needs tests |
309
+ | `package.json` | Dependencies, scripts | Adding dev dependencies |
310
+ | `tsconfig.json` | TypeScript config | Changing TS behavior |
311
+
312
+ ---
313
+
314
+ ## Next Steps
315
+
316
+ 1. **Read [CLAUDE.md](CLAUDE.md)** for detailed rules and patterns
317
+ 2. **Read [PRODUCTION-GUIDE.md](PRODUCTION-GUIDE.md)** for production best practices
318
+ 3. **Review [QUICK-REFERENCE.md](QUICK-REFERENCE.md)** for quick lookups
319
+ 4. **Start developing** — pick a task and follow the workflow above
320
+
321
+ ---
322
+
323
+ ## Quick Start
324
+
325
+ ```typescript
326
+ import { defineContract, t } from '@voltom/contracts'
327
+ import type { SingleResponse, PaginatedResponse, ApiError } from '@voltom/contracts'
328
+
329
+ // Define a contract
330
+ export const usersContract = defineContract({
331
+ resource: 'users',
332
+ basePath: '/api/v1/users',
333
+ entity: {
334
+ id: t.uuid(),
335
+ email: t.email(),
336
+ name: t.string({ min: 1, max: 255 }),
337
+ createdAt: t.datetime(),
338
+ },
339
+ endpoints: {
340
+ list: { method: 'GET', path: '/', response: 'paginated' },
341
+ show: { method: 'GET', path: '/:id', response: 'single' },
342
+ create: { method: 'POST', path: '/', body: 'CreateUser' },
343
+ delete: { method: 'DELETE', path: '/:id', response: 'deleted' },
344
+ },
345
+ bodies: {
346
+ CreateUser: {
347
+ email: t.email(),
348
+ name: t.string({ min: 1, max: 255 }),
349
+ },
350
+ },
351
+ })
352
+ ```
353
+
354
+ ## What's Included
355
+
356
+ ### 1. Primitive Type Builders (`t.*`)
357
+
358
+ ```typescript
359
+ t.uuid() // UUID string
360
+ t.string({ min, max }) // string with constraints
361
+ t.email() // email format
362
+ t.number() // number
363
+ t.int() // integer
364
+ t.boolean() // boolean
365
+ t.datetime() // ISO 8601 datetime
366
+ t.date() // ISO 8601 date
367
+ t.enum(['a', 'b']) // enum
368
+ t.optional(schema) // optional<T>
369
+ t.nullable(schema) // nullable<T>
370
+ t.array(schema) // T[]
371
+ ```
372
+
373
+ ### 2. Response Shapes (Canonical)
374
+
375
+ ```typescript
376
+ SingleResponse<T> // { data: T, timestamp: string }
377
+ PaginatedResponse<T> // { data: T[], meta: PaginationMeta, timestamp: string }
378
+ DeletedResponse // { deleted: true, id: string, timestamp: string }
379
+ ApiError // { error: { code: ErrorCode, message: string }, timestamp: string }
380
+ ```
381
+
382
+ ### 3. Error Codes
383
+
384
+ ```typescript
385
+ type ErrorCode =
386
+ | 'VALIDATION_ERROR' // 400 — invalid input
387
+ | 'UNAUTHORIZED' // 401 — no session
388
+ | 'FORBIDDEN' // 403 — not allowed
389
+ | 'NOT_FOUND' // 404 — missing resource
390
+ | 'CONFLICT' // 409 — duplicate or bad state
391
+ | 'UNPROCESSABLE' // 422 — business logic rejected
392
+ | 'INTERNAL_ERROR' // 500 — server error
393
+
394
+ // Map to HTTP status
395
+ import { ERROR_STATUS_MAP } from '@voltom/contracts'
396
+ const status = ERROR_STATUS_MAP['VALIDATION_ERROR'] // 400
397
+ ```
398
+
399
+ ### 4. `defineContract()` Engine
400
+
401
+ Type-safe contract definition for every resource in your product:
402
+
403
+ ```typescript
404
+ interface ContractConfig {
405
+ resource: string // e.g., 'users'
406
+ basePath: string // e.g., '/api/v1/users'
407
+ entity: Record<string, z.ZodTypeAny> // the shape
408
+ endpoints?: Record<string, EndpointDef> // GET, POST, etc.
409
+ bodies?: Record<string, Record<string, z.ZodTypeAny>> // request bodies
410
+ filters?: Record<string, z.ZodTypeAny> // query filters
411
+ actions?: Record<string, ActionDef> // custom actions
412
+ permissions?: Record<string, string> // access control hints
413
+ }
414
+ ```
415
+
416
+ ## Installation
417
+
418
+ ```bash
419
+ npm install @voltom/contracts zod
420
+ ```
421
+
422
+ ## Usage in Different Contexts
423
+
424
+ ### In Product Contracts (`{product}-contracts`)
425
+
426
+ ```typescript
427
+ import { defineContract, t } from '@voltom/contracts'
428
+
429
+ export const teamsContract = defineContract({
430
+ // ... your contract definition
431
+ })
432
+ ```
433
+
434
+ ### In Backend (NestJS)
435
+
436
+ ```typescript
437
+ import type { SingleResponse, ApiError, ErrorCode } from '@voltom/contracts'
438
+ import { ERROR_STATUS_MAP } from '@voltom/contracts'
439
+
440
+ // Use in controllers, services, interceptors
441
+ ```
442
+
443
+ ### In Frontend (React/Next.js)
444
+
445
+ ```typescript
446
+ import type { PaginatedResponse, ApiError } from '@voltom/contracts'
447
+
448
+ // Use in API calls, type inference
449
+ ```
450
+
451
+ ## Versioning
452
+
453
+ - **patch**: bug fixes (1.0.x)
454
+ - **minor**: new types, additive changes (1.x.0)
455
+ - **major**: breaking changes — requires coordination (x.0.0)
456
+
457
+ ## Development
458
+
459
+ ```bash
460
+ npm install # Install dependencies
461
+ npm run dev # Watch mode
462
+ npm run build # Build (CJS + ESM + .d.ts)
463
+ npm run type-check # TypeScript check
464
+ npm run test # Run tests
465
+ npm run test:watch # Watch mode for tests
466
+ ```
467
+
468
+ ## Publishing
469
+
470
+ 1. Make changes
471
+ 2. `npx changeset` — create changeset
472
+ 3. PR → review → merge to main
473
+ 4. CI publishes automatically to GitHub Packages
474
+ 5. Version bumped, CHANGELOG updated
475
+
476
+ ## See Also
477
+
478
+ - [Platform Overview](../docs/00-PLATFORM-OVERVIEW.md)
479
+ - [Project Identity](../docs/PROJECT-IDENTITY.md)
480
+ - [Full Contract Documentation](../docs/01-CONTRACTS-BASE.md)
481
+
482
+ ---
483
+
484
+ **Organization:** voltom
485
+ **Status:** Active
486
+ **License:** MIT