Skip to content

Commit

Permalink
feat: Add customer and product IDs and expiration date to create a li…
Browse files Browse the repository at this point in the history
…cense in DB.
  • Loading branch information
flemzord committed May 2, 2024
1 parent d5218d4 commit a1d43c0
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 47 deletions.
1 change: 0 additions & 1 deletion apps/web/components/CustomerTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ const { $client } = useNuxtApp();
const { data: customer } = await $client.customer.all.useQuery();
async function deleteToken(id) {
console.log('deleteToken', id);
await $client.customer.delete.mutate({ id });
toast.add({ title: 'Customer deleted', timeout: 5000, color: 'red' });
await refreshNuxtData();
Expand Down
26 changes: 23 additions & 3 deletions apps/web/components/LicenseModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@
<UInput v-model="state.name" />
</UFormGroup>

<UFormGroup label="Select your Article" name="article_id">
<USelect v-model="state.productId" :options="products" option-attribute="name" value-attribute="id" required>
</USelect>
</UFormGroup>

<UFormGroup label="Select your Customer" name="customer_id">
<USelect v-model="state.customerId" :options="customers" option-attribute="name" value-attribute="id" required />
</UFormGroup>

<UFormGroup label="Expiration Date" name="expiration_date">
<UInput v-model="state.expirationDate" type="date" />
</UFormGroup>

<UButton type="submit" class="bg-indigo-600 hover:bg-indigo-900">
Submit
</UButton>
Expand Down Expand Up @@ -51,19 +64,26 @@ import type { FormSubmitEvent } from '#ui/types';
const schema = z.object({
name: z.string().min(3, 'Must be at least 3 characters'),
customerId: z.string().uuid(),
productId: z.string().uuid(),
expirationDate: z.string(),
});
type Schema = z.output<typeof schema>;
const state = reactive({
name: undefined,
customerId: undefined,
productId: undefined,
expirationDate: undefined,
});
async function onSubmit(event: FormSubmitEvent<Schema>) {
const { $client } = useNuxtApp();
const { $client } = useNuxtApp();
const { data: customers } = await $client.customer.all.useQuery();
const { data: products } = await $client.product.all.useQuery();
async function onSubmit(event: FormSubmitEvent<Schema>) {
const add = await $client.license.add.mutate(event.data);
console.log('add', add[0].token);
ticketsModalOpen.value = false;
toast.add({
title: 'License created',
Expand Down
26 changes: 17 additions & 9 deletions apps/web/components/LicenseTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,25 @@
</span>
</a>
</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0">
<a href="#" class="group inline-flex">
Created At
Product Name
<span class="invisible ml-2 flex-none rounded text-gray-400 group-hover:visible group-focus:visible">
<ChevronDownIcon class="invisible ml-2 h-5 w-5 flex-none rounded text-gray-400 group-hover:visible group-focus:visible" aria-hidden="true" />
<ChevronDownIcon class="h-5 w-5" aria-hidden="true" />
</span>
</a>
</th>
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-0">
<a href="#" class="group inline-flex">
Customer Name
<span class="invisible ml-2 flex-none rounded text-gray-400 group-hover:visible group-focus:visible">
<ChevronDownIcon class="h-5 w-5" aria-hidden="true" />
</span>
</a>
</th>
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
<a href="#" class="group inline-flex">
Updated At
Created At
<span class="invisible ml-2 flex-none rounded text-gray-400 group-hover:visible group-focus:visible">
<ChevronDownIcon class="invisible ml-2 h-5 w-5 flex-none rounded text-gray-400 group-hover:visible group-focus:visible" aria-hidden="true" />
</span>
Expand All @@ -48,11 +56,12 @@
</thead>
<tbody class="divide-y divide-gray-200 bg-white">
<tr v-for="token of license" :key="token.id">
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">{{ token.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.createdAt }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.updatedAt }}</td>
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-0">{{ token.License.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.Product.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.Customer.name }}</td>
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">{{ token.License.createdAt }}</td>
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm sm:pr-0">
<UButton @click="deleteToken(token.id)" class="bg-red-600 hover:bg-red-500">
<UButton @click="deleteToken(token.License.id)" class="bg-red-600 hover:bg-red-500">
Delete
</UButton>
</td>
Expand All @@ -76,7 +85,6 @@ const { $client } = useNuxtApp();
const { data: license } = await $client.license.all.useQuery();
async function deleteToken(id) {
console.log('deleteToken', id);
await $client.license.delete.mutate({ id });
toast.add({ title: 'License deleted', timeout: 5000, color: 'red' });
await refreshNuxtData();
Expand Down
1 change: 0 additions & 1 deletion apps/web/components/ProductTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ const { $client } = useNuxtApp();
const { data: product } = await $client.product.all.useQuery();
async function deleteToken(id) {
console.log('deleteToken', id);
await $client.product.delete.mutate({ id });
toast.add({ title: 'Product deleted', timeout: 5000, color: 'red' });
await refreshNuxtData();
Expand Down
14 changes: 14 additions & 0 deletions apps/web/server/trpc/routers/license.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { generateLicenseKey } from '~/server/utils/license';

const AddShape = z.object({
name: z.string(),
customerId: z.string().uuid(),
productId: z.string().uuid(),
expirationDate: z.string(),
});

const DeleteShape = z.object({
Expand All @@ -17,6 +20,14 @@ export const licenseRouter = t.router({
return useDB()
.select()
.from(schema.license)
.innerJoin(
schema.customer,
eq(schema.license.customerId, schema.customer.id),
)
.innerJoin(
schema.product,
eq(schema.license.productId, schema.product.id),
)
.where(eq(schema.license.userId, ctx.userId))
.orderBy(desc(schema.license.createdAt));
}),
Expand All @@ -26,7 +37,10 @@ export const licenseRouter = t.router({
.values({
name: input.name,
userId: ctx.userId,
customerId: input.customerId,
productId: input.productId,
token: generateLicenseKey,
expiresAt: new Date(input.expirationDate),
})
.returning();
}),
Expand Down
3 changes: 0 additions & 3 deletions apps/web/server/trpc/trpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ export const t = initTRPC.context<Context>().create({
});

const isAuthed = t.middleware(({ next, ctx }) => {
// console.log('toto: ', ctx.user.length)
// console.log('toto2: ', ctx.user)
// console.log('toto3: ', ctx.session)
if (ctx.user.length === 0 || ctx.user.length > 1) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ CREATE TABLE IF NOT EXISTS "Customer" (
"name" text NOT NULL,
"metadata" jsonb DEFAULT '{}'::jsonb,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "License" (
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
"user_id" uuid NOT NULL,
"product_id" uuid NOT NULL,
"customer_id" uuid NOT NULL,
"license" text NOT NULL,
"name" text NOT NULL,
"metadata" jsonb DEFAULT '{}'::jsonb,
"expires_at" timestamp,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "Product" (
Expand All @@ -25,8 +26,7 @@ CREATE TABLE IF NOT EXISTS "Product" (
"name" text NOT NULL,
"metadata" jsonb DEFAULT '{}'::jsonb,
"created_at" timestamp DEFAULT now() NOT NULL,
"updated_at" timestamp DEFAULT now() NOT NULL,
"deleted_at" timestamp
"updated_at" timestamp DEFAULT now() NOT NULL
);
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS "User" (
Expand All @@ -50,6 +50,18 @@ EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "License" ADD CONSTRAINT "License_product_id_Product_id_fk" FOREIGN KEY ("product_id") REFERENCES "Product"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "License" ADD CONSTRAINT "License_customer_id_Customer_id_fk" FOREIGN KEY ("customer_id") REFERENCES "Customer"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
WHEN duplicate_object THEN null;
END $$;
--> statement-breakpoint
DO $$ BEGIN
ALTER TABLE "Product" ADD CONSTRAINT "Product_user_id_User_id_fk" FOREIGN KEY ("user_id") REFERENCES "User"("id") ON DELETE no action ON UPDATE no action;
EXCEPTION
Expand Down
64 changes: 45 additions & 19 deletions internal/db/src/migrations/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"id": "941419f1-ea4e-444d-aa69-dc7d26f54967",
"id": "91d720f3-8462-4101-a0d0-a7733a84162e",
"prevId": "00000000-0000-0000-0000-000000000000",
"version": "5",
"dialect": "pg",
Expand Down Expand Up @@ -47,12 +47,6 @@
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
Expand Down Expand Up @@ -91,6 +85,18 @@
"primaryKey": false,
"notNull": true
},
"product_id": {
"name": "product_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"customer_id": {
"name": "customer_id",
"type": "uuid",
"primaryKey": false,
"notNull": true
},
"license": {
"name": "license",
"type": "text",
Expand All @@ -110,6 +116,12 @@
"notNull": false,
"default": "'{}'::jsonb"
},
"expires_at": {
"name": "expires_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp",
Expand All @@ -123,12 +135,6 @@
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
Expand All @@ -145,6 +151,32 @@
],
"onDelete": "no action",
"onUpdate": "no action"
},
"License_product_id_Product_id_fk": {
"name": "License_product_id_Product_id_fk",
"tableFrom": "License",
"tableTo": "Product",
"columnsFrom": [
"product_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
},
"License_customer_id_Customer_id_fk": {
"name": "License_customer_id_Customer_id_fk",
"tableFrom": "License",
"tableTo": "Customer",
"columnsFrom": [
"customer_id"
],
"columnsTo": [
"id"
],
"onDelete": "no action",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
Expand Down Expand Up @@ -193,12 +225,6 @@
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamp",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
Expand Down
4 changes: 2 additions & 2 deletions internal/db/src/migrations/meta/_journal.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
{
"idx": 0,
"version": "5",
"when": 1714639399840,
"tag": "0000_high_firebrand",
"when": 1714640966914,
"tag": "0000_modern_captain_flint",
"breakpoints": true
}
]
Expand Down
10 changes: 7 additions & 3 deletions internal/db/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,18 @@ export const license = pgTable('License', {
userId: uuid('user_id')
.notNull()
.references(() => user.id),
productId: uuid('product_id')
.notNull()
.references(() => product.id),
customerId: uuid('customer_id')
.notNull()
.references(() => customer.id),
token: text('license').notNull(),
name: text('name').notNull(),
metadata: jsonb('metadata').default(sql`'{}'::jsonb`),
expiresAt: timestamp('expires_at'),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
deletedAt: timestamp('deleted_at'),
});

export const licenseRelations = relations(user, ({ one }) => ({
Expand All @@ -41,7 +47,6 @@ export const product = pgTable('Product', {
metadata: jsonb('metadata').default(sql`'{}'::jsonb`),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
deletedAt: timestamp('deleted_at'),
});

export const customer = pgTable('Customer', {
Expand All @@ -53,5 +58,4 @@ export const customer = pgTable('Customer', {
metadata: jsonb('metadata').default(sql`'{}'::jsonb`),
createdAt: timestamp('created_at').notNull().defaultNow(),
updatedAt: timestamp('updated_at').notNull().defaultNow(),
deletedAt: timestamp('deleted_at'),
});

0 comments on commit a1d43c0

Please sign in to comment.