feat: tiered costs feature + admin tier management + tag selection
Build & Push Docker Image / build (push) Successful in 6m52s
Build & Push Docker Image / build (push) Successful in 6m52s
- costs: nullable notes (fix create without notes), drop renewalDate (schema + API + UI), gate POST/PATCH/DELETE to admin + costs feature - feature middleware: admin-aware hasFeature + getEntitlements union; /auth/me and login return resolved entitlements - users: tier enum (free/premium/enterprise) in create/update/list, admin UI tier select + tier badge - tags: GET /tags/all, TagInput autocomplete in new/edit tool forms, feature suggestions on focus, query invalidation on create/update - openapi: nullable ToolUpdate urls, ToolUpdate tier fields, listAllTags - Dockerfile: push-force to drop renewal_date column
This commit is contained in:
@@ -105,8 +105,8 @@ export const UpdateToolBody = zod.object({
|
||||
"name": zod.string().min(1).optional(),
|
||||
"description": zod.string().optional(),
|
||||
"category": zod.string().optional(),
|
||||
"websiteUrl": zod.string().nullable().optional(),
|
||||
"iconUrl": zod.string().nullable().optional(),
|
||||
"websiteUrl": zod.string().nullish(),
|
||||
"iconUrl": zod.string().nullish(),
|
||||
"features": zod.array(zod.string()).optional(),
|
||||
"tags": zod.array(zod.string()).optional()
|
||||
})
|
||||
@@ -288,6 +288,13 @@ export const ListAllFeaturesResponseItem = zod.string()
|
||||
export const ListAllFeaturesResponse = zod.array(ListAllFeaturesResponseItem)
|
||||
|
||||
|
||||
/**
|
||||
* @summary List all distinct tag strings across all tools
|
||||
*/
|
||||
export const ListAllTagsResponseItem = zod.string()
|
||||
export const ListAllTagsResponse = zod.array(ListAllTagsResponseItem)
|
||||
|
||||
|
||||
/**
|
||||
* @summary Get authentication mode (oidc or local)
|
||||
*/
|
||||
@@ -310,6 +317,8 @@ export const LocalLoginResponse = zod.object({
|
||||
"name": zod.string().nullish(),
|
||||
"preferredUsername": zod.string().nullish(),
|
||||
"role": zod.enum(['admin', 'user']).optional(),
|
||||
"tier": zod.enum(['free', 'premium', 'enterprise']).optional(),
|
||||
"entitlements": zod.array(zod.string()).optional(),
|
||||
"isLocal": zod.boolean().optional()
|
||||
})
|
||||
|
||||
@@ -323,6 +332,8 @@ export const GetMeResponse = zod.object({
|
||||
"name": zod.string().nullish(),
|
||||
"preferredUsername": zod.string().nullish(),
|
||||
"role": zod.enum(['admin', 'user']).optional(),
|
||||
"tier": zod.enum(['free', 'premium', 'enterprise']).optional(),
|
||||
"entitlements": zod.array(zod.string()).optional(),
|
||||
"isLocal": zod.boolean().optional()
|
||||
})
|
||||
|
||||
@@ -335,6 +346,7 @@ export const ListUsersResponseItem = zod.object({
|
||||
"username": zod.string(),
|
||||
"email": zod.string().nullish(),
|
||||
"role": zod.enum(['admin', 'user']),
|
||||
"tier": zod.enum(['free', 'premium', 'enterprise']).optional(),
|
||||
"createdAt": zod.coerce.date()
|
||||
})
|
||||
export const ListUsersResponse = zod.array(ListUsersResponseItem)
|
||||
@@ -353,7 +365,8 @@ export const CreateUserBody = zod.object({
|
||||
"username": zod.string().min(createUserBodyUsernameMin),
|
||||
"password": zod.string().min(createUserBodyPasswordMin),
|
||||
"email": zod.string().optional(),
|
||||
"role": zod.enum(['admin', 'user']).optional()
|
||||
"role": zod.enum(['admin', 'user']).optional(),
|
||||
"tier": zod.enum(['free', 'premium', 'enterprise']).optional()
|
||||
})
|
||||
|
||||
|
||||
@@ -365,7 +378,8 @@ export const UpdateUserParams = zod.object({
|
||||
})
|
||||
|
||||
export const UpdateUserBody = zod.object({
|
||||
"role": zod.enum(['admin', 'user'])
|
||||
"role": zod.enum(['admin', 'user']).optional(),
|
||||
"tier": zod.enum(['free', 'premium', 'enterprise']).optional()
|
||||
})
|
||||
|
||||
export const UpdateUserResponse = zod.object({
|
||||
@@ -373,6 +387,7 @@ export const UpdateUserResponse = zod.object({
|
||||
"username": zod.string(),
|
||||
"email": zod.string().nullish(),
|
||||
"role": zod.enum(['admin', 'user']),
|
||||
"tier": zod.enum(['free', 'premium', 'enterprise']).optional(),
|
||||
"createdAt": zod.coerce.date()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user