xtablo-source/docs/TYPES_PACKAGE.md

303 lines
7.5 KiB
Markdown
Raw Permalink Normal View History

2025-11-10 07:53:03 +00:00
# Types Package - @xtablo/shared-types
## Overview
The `@xtablo/shared-types` package is a dedicated TypeScript types package that provides shared type definitions across all apps in the Xtablo monorepo. It serves as a single source of truth for all type definitions, ensuring consistency and reducing duplication.
## Why a Separate Types Package?
1. **Zero Dependencies**: Unlike the `@xtablo/shared` package which has React and other runtime dependencies, `@xtablo/shared-types` is pure TypeScript with zero dependencies
2. **Universal Usage**: Can be used by all apps (API, frontend, mobile) without bringing in unnecessary dependencies
3. **Better Organization**: Clear separation between types and implementation code
4. **Faster Builds**: No runtime code means faster type checking
5. **Easy to Update**: Database types can be regenerated and all apps automatically get the updates
## Package Structure
```
packages/shared-types/
├── src/
│ ├── database.types.ts # Supabase-generated database types (855 lines)
│ ├── events.types.ts # Event-related domain types
│ ├── tablos.types.ts # Tablo-related domain types
│ ├── stripe.types.ts # Stripe integration types
│ ├── kanban.types.ts # Kanban board types (149 lines)
│ ├── utils.ts # Utility types (Tables, TablesInsert, etc.)
│ └── index.ts # Main export file
├── package.json
├── tsconfig.json
├── biome.json
├── turbo.json
└── README.md
```
## Type Categories
### 1. Database Types (`database.types.ts`)
Auto-generated from Supabase schema:
```typescript
export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[];
export type Database = {
public: {
Tables: { /* all tables */ },
Views: { /* all views */ },
Functions: { /* all functions */ },
Enums: { /* all enums */ }
}
};
```
### 2. Utility Types (`utils.ts`)
Helper types for working with the database:
```typescript
// Extract table row types
type Tables<TableName> = Database["public"]["Tables"][TableName]["Row"];
// Extract insert types
type TablesInsert<TableName> = Database["public"]["Tables"][TableName]["Insert"];
// Extract update types
type TablesUpdate<TableName> = Database["public"]["Tables"][TableName]["Update"];
// Remove null from types
type RemoveNull<T> = T extends null ? never : T;
type RemoveNullFromObject<T, K extends keyof T = keyof T> = {
[L in keyof T]: L extends K ? RemoveNull<T[L]> : T[L];
};
```
### 3. Domain Types
#### Events (`events.types.ts`)
```typescript
export type Event = RemoveNullFromObject<Tables<"events">, "created_at" | "end_time">;
export type EventInsert = TablesInsert<"events">;
export type EventUpdate = TablesUpdate<"events">;
export type EventInsertInTablo = Omit<EventInsert, "tablo_id">;
export type EventAndTablo = RemoveNullFromObject<...>;
```
#### Tablos (`tablos.types.ts`)
```typescript
export type Tablo = Database["public"]["Tables"]["tablos"];
export type TabloInsert = Tablo["Insert"];
export type TabloUpdate = Tablo["Update"];
export type UserTablo = RemoveNullFromObject<...>;
export type CreateTablo = Pick<TabloInsert, ...> & { events?: EventInsertInTablo[] };
```
#### Stripe (`stripe.types.ts`)
All Stripe-related types including:
- `StripeSubscription`, `StripeProduct`, `StripePrice`
- `SubscriptionStatus`, `BillingInterval`
- `PriceWithProduct`, `SubscriptionWithDetails`
#### Kanban (`kanban.types.ts`)
Complete Kanban board types:
- `KanbanTask`, `KanbanBoard`, `KanbanColumn`
- `TaskStatus`, `Priority`, `TaskType`
- `KanbanTaskInsert`, `KanbanTaskUpdate`
## Usage in Apps
### API (apps/api)
Add to `package.json`:
```json
{
"dependencies": {
"@xtablo/shared-types": "workspace:*"
}
}
```
Usage:
```typescript
import type { Event, Tablo, TablesInsert } from "@xtablo/shared-types";
// In router handlers
export async function createEvent(data: TablesInsert<"events">) {
// Implementation
}
```
### Frontend Apps (apps/main, apps/external)
Add to `package.json`:
```json
{
"dependencies": {
"@xtablo/shared-types": "workspace:*"
}
}
```
Usage:
```typescript
import type { Event, UserTablo, StripePrice } from "@xtablo/shared-types";
interface EventCardProps {
event: Event;
}
function EventCard({ event }: EventCardProps) {
// Component implementation
}
```
### Shared Package (packages/shared)
The shared package can re-export types for convenience:
```typescript
// In packages/shared/src/index.ts
export type {
Event,
Tablo,
UserTablo,
StripeSubscription,
} from "@xtablo/shared-types";
```
## Updating Database Types
When the Supabase schema changes, regenerate the types:
```bash
# Generate new types from Supabase
npx supabase gen types typescript --project-id YOUR_PROJECT_ID > packages/shared-types/src/database.types.ts
# Or if you have the Supabase CLI configured
cd packages/shared-types
supabase gen types typescript --local > src/database.types.ts
# Format the generated file
cd /Users/arthur.belleville/Documents/perso/projects/xtablo-source
turbo run format --filter=@xtablo/shared-types
```
All apps will automatically get the updated types on their next build.
## Advantages
### Before (Duplicated Types)
```
apps/api/src/types/database.types.ts (855 lines)
packages/shared/src/types/database.types.ts (855 lines)
// Types duplicated, can get out of sync
```
### After (Single Source)
```
packages/shared-types/src/database.types.ts (855 lines)
// Single source, always in sync
// Used by:
// - apps/api
// - apps/main
// - apps/external
// - packages/shared
// - xtablo-expo
```
## Configuration Files
### package.json
- Zero dependencies (only dev dependencies for tooling)
- Exports configuration for granular imports
- Standard scripts: `typecheck`, `lint`, `lint:fix`, `format`
### tsconfig.json
- Strict mode enabled
- ESNext module resolution
- Declaration files enabled
### biome.json
- Consistent formatting rules with rest of monorepo
- Import sorting enabled
- Strict linting rules
### turbo.json
- Extends root configuration
- No build step (types only)
## Scripts
From the root:
```bash
# Type check the types package
turbo run typecheck --filter=@xtablo/shared-types
# Lint the types package
turbo run lint --filter=@xtablo/shared-types
turbo run lint:fix --filter=@xtablo/shared-types
# Format code
turbo run format --filter=@xtablo/shared-types
```
## Migration Path
To migrate an app to use `@xtablo/shared-types`:
1. **Add dependency**:
```bash
cd apps/your-app
pnpm add @xtablo/shared-types@workspace:*
```
2. **Update imports**:
```typescript
// Before
import type { Event } from "../types/events";
// After
import type { Event } from "@xtablo/shared-types";
```
3. **Remove local type files** if they're now in `@xtablo/shared-types`
4. **Run type checking** to ensure everything works:
```bash
turbo run typecheck --filter=your-app
```
## Best Practices
1. **Keep types pure**: No runtime code, only type definitions
2. **Use utility types**: Leverage `Tables`, `TablesInsert`, etc. for consistency
3. **Document complex types**: Add JSDoc comments for non-obvious types
4. **Version control**: Commit database type regenerations as a single commit
5. **Test changes**: Run `turbo run typecheck` before committing type changes
## Verification
All type checks pass:
```bash
✅ turbo run typecheck --filter=@xtablo/shared-types
✅ turbo run lint --filter=@xtablo/shared-types
```
The types package is now ready to be used across all apps in the monorepo!