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:
@@ -4,6 +4,7 @@ import bcrypt from "bcryptjs";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { db, usersTable } from "@workspace/db";
|
||||
import { logger } from "../lib/logger";
|
||||
import { getEntitlements } from "../middleware/feature";
|
||||
|
||||
const router: IRouter = Router();
|
||||
|
||||
@@ -155,6 +156,7 @@ router.post("/auth/login", async (req, res): Promise<void> => {
|
||||
preferredUsername: user.username,
|
||||
role: user.role,
|
||||
tier: user.tier,
|
||||
entitlements: getEntitlements(user.tier, user.role),
|
||||
isLocal: true,
|
||||
});
|
||||
});
|
||||
@@ -271,6 +273,7 @@ router.get("/auth/me", async (req, res): Promise<void> => {
|
||||
preferredUsername: u.preferred_username ?? null,
|
||||
role: u.role ?? "user",
|
||||
tier: u.tier ?? "free",
|
||||
entitlements: getEntitlements(u.tier, u.role),
|
||||
isLocal: u.isLocal ?? false,
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user