Rebuild admin pages around DataTable/AdminModal; restructure categories/groups and v2 groups API

Remove the generic $lib/svelte-admin CRUD layer and AdminTable.svelte; each
admin route now owns its own form/modal logic. Add DataTable.svelte,
superform-errors.ts, and profile-specific modal/field components.

Flatten proclamation categories/groups and drop subscription levels; add the
v2 groups API; update v1/v2 endpoints, serializers, auth, and regenerated
Prisma client with the new migrations.

Document the overhaul plan in docs/ADMIN_OVERHAUL.md.
This commit is contained in:
NeilClack
2026-09-10 09:38:01 -05:00
parent f4e736c92d
commit 91d162c746
127 changed files with 7182 additions and 9785 deletions
+79 -60
View File
@@ -28,24 +28,24 @@ export type LicenseKeyMinAggregateOutputType = {
id: string | null
key: string | null
active: boolean | null
level: string | null
userId: string | null
email: string | null
}
export type LicenseKeyMaxAggregateOutputType = {
id: string | null
key: string | null
active: boolean | null
level: string | null
userId: string | null
email: string | null
}
export type LicenseKeyCountAggregateOutputType = {
id: number
key: number
active: number
level: number
userId: number
email: number
_all: number
}
@@ -54,24 +54,24 @@ export type LicenseKeyMinAggregateInputType = {
id?: true
key?: true
active?: true
level?: true
userId?: true
email?: true
}
export type LicenseKeyMaxAggregateInputType = {
id?: true
key?: true
active?: true
level?: true
userId?: true
email?: true
}
export type LicenseKeyCountAggregateInputType = {
id?: true
key?: true
active?: true
level?: true
userId?: true
email?: true
_all?: true
}
@@ -151,8 +151,8 @@ export type LicenseKeyGroupByOutputType = {
id: string
key: string
active: boolean
level: string
userId: string
userId: string | null
email: string | null
_count: LicenseKeyCountAggregateOutputType | null
_min: LicenseKeyMinAggregateOutputType | null
_max: LicenseKeyMaxAggregateOutputType | null
@@ -180,17 +180,17 @@ export type LicenseKeyWhereInput = {
id?: Prisma.StringFilter<"LicenseKey"> | string
key?: Prisma.StringFilter<"LicenseKey"> | string
active?: Prisma.BoolFilter<"LicenseKey"> | boolean
level?: Prisma.StringFilter<"LicenseKey"> | string
userId?: Prisma.StringFilter<"LicenseKey"> | string
user?: Prisma.XOR<Prisma.UserScalarRelationFilter, Prisma.UserWhereInput>
userId?: Prisma.StringNullableFilter<"LicenseKey"> | string | null
email?: Prisma.StringNullableFilter<"LicenseKey"> | string | null
user?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
}
export type LicenseKeyOrderByWithRelationInput = {
id?: Prisma.SortOrder
key?: Prisma.SortOrder
active?: Prisma.SortOrder
level?: Prisma.SortOrder
userId?: Prisma.SortOrder
userId?: Prisma.SortOrderInput | Prisma.SortOrder
email?: Prisma.SortOrderInput | Prisma.SortOrder
user?: Prisma.UserOrderByWithRelationInput
}
@@ -201,17 +201,17 @@ export type LicenseKeyWhereUniqueInput = Prisma.AtLeast<{
OR?: Prisma.LicenseKeyWhereInput[]
NOT?: Prisma.LicenseKeyWhereInput | Prisma.LicenseKeyWhereInput[]
active?: Prisma.BoolFilter<"LicenseKey"> | boolean
level?: Prisma.StringFilter<"LicenseKey"> | string
userId?: Prisma.StringFilter<"LicenseKey"> | string
user?: Prisma.XOR<Prisma.UserScalarRelationFilter, Prisma.UserWhereInput>
userId?: Prisma.StringNullableFilter<"LicenseKey"> | string | null
email?: Prisma.StringNullableFilter<"LicenseKey"> | string | null
user?: Prisma.XOR<Prisma.UserNullableScalarRelationFilter, Prisma.UserWhereInput> | null
}, "id" | "key">
export type LicenseKeyOrderByWithAggregationInput = {
id?: Prisma.SortOrder
key?: Prisma.SortOrder
active?: Prisma.SortOrder
level?: Prisma.SortOrder
userId?: Prisma.SortOrder
userId?: Prisma.SortOrderInput | Prisma.SortOrder
email?: Prisma.SortOrderInput | Prisma.SortOrder
_count?: Prisma.LicenseKeyCountOrderByAggregateInput
_max?: Prisma.LicenseKeyMaxOrderByAggregateInput
_min?: Prisma.LicenseKeyMinOrderByAggregateInput
@@ -224,63 +224,63 @@ export type LicenseKeyScalarWhereWithAggregatesInput = {
id?: Prisma.StringWithAggregatesFilter<"LicenseKey"> | string
key?: Prisma.StringWithAggregatesFilter<"LicenseKey"> | string
active?: Prisma.BoolWithAggregatesFilter<"LicenseKey"> | boolean
level?: Prisma.StringWithAggregatesFilter<"LicenseKey"> | string
userId?: Prisma.StringWithAggregatesFilter<"LicenseKey"> | string
userId?: Prisma.StringNullableWithAggregatesFilter<"LicenseKey"> | string | null
email?: Prisma.StringNullableWithAggregatesFilter<"LicenseKey"> | string | null
}
export type LicenseKeyCreateInput = {
id?: string
key: string
active: boolean
level: string
user: Prisma.UserCreateNestedOneWithoutLicenseKeysInput
email?: string | null
user?: Prisma.UserCreateNestedOneWithoutLicenseKeysInput
}
export type LicenseKeyUncheckedCreateInput = {
id?: string
key: string
active: boolean
level: string
userId: string
userId?: string | null
email?: string | null
}
export type LicenseKeyUpdateInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
user?: Prisma.UserUpdateOneRequiredWithoutLicenseKeysNestedInput
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
user?: Prisma.UserUpdateOneWithoutLicenseKeysNestedInput
}
export type LicenseKeyUncheckedUpdateInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
userId?: Prisma.StringFieldUpdateOperationsInput | string
userId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
}
export type LicenseKeyCreateManyInput = {
id?: string
key: string
active: boolean
level: string
userId: string
userId?: string | null
email?: string | null
}
export type LicenseKeyUpdateManyMutationInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
}
export type LicenseKeyUncheckedUpdateManyInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
userId?: Prisma.StringFieldUpdateOperationsInput | string
userId?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
}
export type LicenseKeyListRelationFilter = {
@@ -297,24 +297,24 @@ export type LicenseKeyCountOrderByAggregateInput = {
id?: Prisma.SortOrder
key?: Prisma.SortOrder
active?: Prisma.SortOrder
level?: Prisma.SortOrder
userId?: Prisma.SortOrder
email?: Prisma.SortOrder
}
export type LicenseKeyMaxOrderByAggregateInput = {
id?: Prisma.SortOrder
key?: Prisma.SortOrder
active?: Prisma.SortOrder
level?: Prisma.SortOrder
userId?: Prisma.SortOrder
email?: Prisma.SortOrder
}
export type LicenseKeyMinOrderByAggregateInput = {
id?: Prisma.SortOrder
key?: Prisma.SortOrder
active?: Prisma.SortOrder
level?: Prisma.SortOrder
userId?: Prisma.SortOrder
email?: Prisma.SortOrder
}
export type LicenseKeyCreateNestedManyWithoutUserInput = {
@@ -363,14 +363,14 @@ export type LicenseKeyCreateWithoutUserInput = {
id?: string
key: string
active: boolean
level: string
email?: string | null
}
export type LicenseKeyUncheckedCreateWithoutUserInput = {
id?: string
key: string
active: boolean
level: string
email?: string | null
}
export type LicenseKeyCreateOrConnectWithoutUserInput = {
@@ -406,36 +406,36 @@ export type LicenseKeyScalarWhereInput = {
id?: Prisma.StringFilter<"LicenseKey"> | string
key?: Prisma.StringFilter<"LicenseKey"> | string
active?: Prisma.BoolFilter<"LicenseKey"> | boolean
level?: Prisma.StringFilter<"LicenseKey"> | string
userId?: Prisma.StringFilter<"LicenseKey"> | string
userId?: Prisma.StringNullableFilter<"LicenseKey"> | string | null
email?: Prisma.StringNullableFilter<"LicenseKey"> | string | null
}
export type LicenseKeyCreateManyUserInput = {
id?: string
key: string
active: boolean
level: string
email?: string | null
}
export type LicenseKeyUpdateWithoutUserInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
}
export type LicenseKeyUncheckedUpdateWithoutUserInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
}
export type LicenseKeyUncheckedUpdateManyWithoutUserInput = {
id?: Prisma.StringFieldUpdateOperationsInput | string
key?: Prisma.StringFieldUpdateOperationsInput | string
active?: Prisma.BoolFieldUpdateOperationsInput | boolean
level?: Prisma.StringFieldUpdateOperationsInput | string
email?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
}
@@ -444,59 +444,59 @@ export type LicenseKeySelect<ExtArgs extends runtime.Types.Extensions.InternalAr
id?: boolean
key?: boolean
active?: boolean
level?: boolean
userId?: boolean
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
email?: boolean
user?: boolean | Prisma.LicenseKey$userArgs<ExtArgs>
}, ExtArgs["result"]["licenseKey"]>
export type LicenseKeySelectCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
id?: boolean
key?: boolean
active?: boolean
level?: boolean
userId?: boolean
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
email?: boolean
user?: boolean | Prisma.LicenseKey$userArgs<ExtArgs>
}, ExtArgs["result"]["licenseKey"]>
export type LicenseKeySelectUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
id?: boolean
key?: boolean
active?: boolean
level?: boolean
userId?: boolean
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
email?: boolean
user?: boolean | Prisma.LicenseKey$userArgs<ExtArgs>
}, ExtArgs["result"]["licenseKey"]>
export type LicenseKeySelectScalar = {
id?: boolean
key?: boolean
active?: boolean
level?: boolean
userId?: boolean
email?: boolean
}
export type LicenseKeyOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "key" | "active" | "level" | "userId", ExtArgs["result"]["licenseKey"]>
export type LicenseKeyOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "key" | "active" | "userId" | "email", ExtArgs["result"]["licenseKey"]>
export type LicenseKeyInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
user?: boolean | Prisma.LicenseKey$userArgs<ExtArgs>
}
export type LicenseKeyIncludeCreateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
user?: boolean | Prisma.LicenseKey$userArgs<ExtArgs>
}
export type LicenseKeyIncludeUpdateManyAndReturn<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
user?: boolean | Prisma.UserDefaultArgs<ExtArgs>
user?: boolean | Prisma.LicenseKey$userArgs<ExtArgs>
}
export type $LicenseKeyPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
name: "LicenseKey"
objects: {
user: Prisma.$UserPayload<ExtArgs>
user: Prisma.$UserPayload<ExtArgs> | null
}
scalars: runtime.Types.Extensions.GetPayloadResult<{
id: string
key: string
active: boolean
level: string
userId: string
userId: string | null
email: string | null
}, ExtArgs["result"]["licenseKey"]>
composites: {}
}
@@ -891,7 +891,7 @@ readonly fields: LicenseKeyFieldRefs;
*/
export interface Prisma__LicenseKeyClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
readonly [Symbol.toStringTag]: "PrismaPromise"
user<T extends Prisma.UserDefaultArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.UserDefaultArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions>
user<T extends Prisma.LicenseKey$userArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.LicenseKey$userArgs<ExtArgs>>): Prisma.Prisma__UserClient<runtime.Types.Result.GetResult<Prisma.$UserPayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | null, null, ExtArgs, GlobalOmitOptions>
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
@@ -924,8 +924,8 @@ export interface LicenseKeyFieldRefs {
readonly id: Prisma.FieldRef<"LicenseKey", 'String'>
readonly key: Prisma.FieldRef<"LicenseKey", 'String'>
readonly active: Prisma.FieldRef<"LicenseKey", 'Boolean'>
readonly level: Prisma.FieldRef<"LicenseKey", 'String'>
readonly userId: Prisma.FieldRef<"LicenseKey", 'String'>
readonly email: Prisma.FieldRef<"LicenseKey", 'String'>
}
@@ -1326,6 +1326,25 @@ export type LicenseKeyDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.In
limit?: number
}
/**
* LicenseKey.user
*/
export type LicenseKey$userArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
/**
* Select specific fields to fetch from the User
*/
select?: Prisma.UserSelect<ExtArgs> | null
/**
* Omit specific fields from the User
*/
omit?: Prisma.UserOmit<ExtArgs> | null
/**
* Choose, which related nodes to fetch as well
*/
include?: Prisma.UserInclude<ExtArgs> | null
where?: Prisma.UserWhereInput
}
/**
* LicenseKey without action
*/