Skip to content

Commit

Permalink
feat(billing): add glossary entry generation workflow (#2642)
Browse files Browse the repository at this point in the history
  • Loading branch information
p6l-richard authored Nov 11, 2024
1 parent 740f8dd commit ba369f9
Show file tree
Hide file tree
Showing 27 changed files with 5,236 additions and 1,359 deletions.
159 changes: 159 additions & 0 deletions apps/billing/cursor/drizzle_instructions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
Drizzle ORM MySQL Model Generation Guide

1. Table Definition:
- Use `mysqlTable` to define tables
- Example:
```typescript
import { mysqlTable, varchar, text, timestamp, int } from 'drizzle-orm/mysql-core';

export const tableName = mysqlTable('table_name', {
id: varchar('id', { length: 255 }).primaryKey(),
name: varchar('name', { length: 255 }).notNull(),
description: text('description'),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().$onUpdate(() => new Date()),
});
```

2. Relations:
- Use `relations` to define relationships between tables
- Ensure that relations are defined in the appropriate files that contain their related models
- Note: Schemas are defined in the src/lib/db-marketing/schemas folder with an index.ts file as barrel.
- Example:
```typescript
import { relations } from 'drizzle-orm';

export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));

export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
```

3. Schemas:
- Use `createInsertSchema` and `createSelectSchema` from 'drizzle-zod' for Zod schemas
- Example:
```typescript
import { createInsertSchema, createSelectSchema } from 'drizzle-zod';

export const insertTableNameSchema = createInsertSchema(tableName);
export const selectTableNameSchema = createSelectSchema(tableName);
```
- Override or refine fields when creating schemas:
```typescript
const insertUserSchema = createInsertSchema(users, {
role: z.string(),
id: (schema) => schema.id.positive(),
email: (schema) => schema.email.email(),
});
```
- Prefer extending or omitting from these exported schemas instead of creating new ones, as they serve as the source of truth
- Example:
```typescript
export const customTableNameSchema = selectTableNameSchema.extend({
newField: z.string(),
});
```

4. Types:
- Use Zod's infer utility with the generated schemas
- Example:
```typescript
export type InsertTableName = z.infer<typeof insertTableNameSchema>;
export type SelectTableName = z.infer<typeof selectTableNameSchema>;
```

5. Junction Tables:
- For many-to-many relationships, create a junction table
- Example:
```typescript
export const junctionTable = mysqlTable('junction_table', {
table1Id: varchar('table1_id', { length: 255 }).notNull(),
table2Id: varchar('table2_id', { length: 255 }).notNull(),
}, (t) => ({
pk: primaryKey({ columns: [t.table1Id, t.table2Id] }),
}));
```

6. Timestamps:
- For `createdAt` and `updatedAt` fields:
```typescript
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().$onUpdate(() => new Date()),
```

7. Prefer Relational Data Modeling:
- Use relational data modeling and separate tables instead of JSON fields when possible
- This improves query performance and maintains better data integrity
- Example: Instead of storing an array of items as JSON, create a separate table and use a foreign key relationship
```typescript
// Instead of:
const users = mysqlTable('users', {
id: varchar('id', { length: 255 }).primaryKey(),
name: varchar('name', { length: 255 }).notNull(),
items: json('items'), // Stores an array of items as JSON
});

// Prefer:
const users = mysqlTable('users', {
id: varchar('id', { length: 255 }).primaryKey(),
name: varchar('name', { length: 255 }).notNull(),
});

const items = mysqlTable('items', {
id: varchar('id', { length: 255 }).primaryKey(),
userId: varchar('user_id', { length: 255 }).notNull(),
name: varchar('name', { length: 255 }).notNull(),
});

const usersRelations = relations(users, ({ many }) => ({
items: many(items),
}));
```

8. Column Types:
- Drizzle supports various MySQL column types, including:
```typescript
import { int, tinyint, smallint, mediumint, bigint } from 'drizzle-orm/mysql-core';

const table = mysqlTable('table', {
tinyIntColumn: tinyint('tiny_int_column'),
smallIntColumn: smallint('small_int_column'),
mediumIntColumn: mediumint('medium_int_column'),
intColumn: int('int_column'),
bigIntColumn: bigint('big_int_column'),
});
```

9. Default Values and Constraints:
- Set default values and constraints on columns:
```typescript
const table = mysqlTable('table', {
intWithDefault: int('int_with_default').default(3),
notNullInt: int('not_null_int').notNull(),
});
```

10. Relational Queries:
- Perform nested relational queries:
```typescript
const result = await db.query.users.findMany({
with: {
posts: true
},
});
```

11. Best Practices:
- Co-locate relations, schemas, and types with their respective model definitions
- Use meaningful and consistent naming conventions
- Define primary keys and foreign keys appropriately
- Use the correct data types and lengths for your fields

Remember to import necessary functions and types from 'drizzle-orm' and 'drizzle-orm/mysql-core'.
Remember that these are just guidelines & examples. Ensure you use the correct types & schemas for your tables and relations.
Loading

0 comments on commit ba369f9

Please sign in to comment.