mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
fix(freight-permissions): split company stamp from per-officer teeter permission
This commit is contained in:
@@ -15,21 +15,21 @@ export class StampSettingsController {
|
||||
constructor(private readonly service: StampSettingsService) {}
|
||||
|
||||
@Get()
|
||||
@BookingStaff([FREIGHT_PERMS.settings.invoiceStamp.view, FREIGHT_PERMS.admin])
|
||||
@BookingStaff([FREIGHT_PERMS.settings.stamp.view, FREIGHT_PERMS.admin])
|
||||
@ApiOperation({ summary: "Current company stamp used on invoice/receipt PDFs" })
|
||||
get() {
|
||||
return this.service.getView();
|
||||
}
|
||||
|
||||
@Put()
|
||||
@BookingStaff([FREIGHT_PERMS.settings.invoiceStamp.manage, FREIGHT_PERMS.admin])
|
||||
@BookingStaff([FREIGHT_PERMS.settings.stamp.manage, FREIGHT_PERMS.admin])
|
||||
@ApiOperation({ summary: "Replace the company stamp" })
|
||||
update(@Body() dto: UpdateStampSettingDto, @CurrentUser() user: TCurrentUser) {
|
||||
return this.service.setStamp(dto.stampImageBase64, user?.id ?? null);
|
||||
}
|
||||
|
||||
@Delete()
|
||||
@BookingStaff([FREIGHT_PERMS.settings.invoiceStamp.manage, FREIGHT_PERMS.admin])
|
||||
@BookingStaff([FREIGHT_PERMS.settings.stamp.manage, FREIGHT_PERMS.admin])
|
||||
@ApiOperation({
|
||||
summary: "Clear the company stamp (invoices fall back to the plain seal)",
|
||||
})
|
||||
|
||||
@@ -1190,22 +1190,28 @@ export const CONFIG_SETTINGS_PERMISSIONS: FreightPermissionSeed[] = [
|
||||
perm(
|
||||
"b4b00002-0001-4000-8000-000000000001",
|
||||
"edr_freight_app:settings:stamp:view",
|
||||
"View stamp settings",
|
||||
"View the company stamp",
|
||||
),
|
||||
perm(
|
||||
"b4b00002-0001-4000-8000-000000000002",
|
||||
"edr_freight_app:settings:stamp:manage",
|
||||
"Manage stamp settings",
|
||||
"Manage the company stamp",
|
||||
),
|
||||
// The per-officer approval teeter (ማህተም) — an individual's own stamp +
|
||||
// signature, not the company seal. It used to ride on settings:stamp:*, which
|
||||
// now gates the ONE company stamp; this key was split out when the two were
|
||||
// untangled. `settings:invoice_stamp:*` retired at the same time: it gated the
|
||||
// company stamp before the fold and is deliberately left orphaned in any DB
|
||||
// that already seeded it (the seeder upserts by key and never deletes).
|
||||
perm(
|
||||
"b4b00003-0001-4000-8000-000000000001",
|
||||
"edr_freight_app:settings:invoice_stamp:view",
|
||||
"View invoice stamp settings",
|
||||
"edr_freight_app:settings:teeter:view",
|
||||
"View own approval teeter and signature",
|
||||
),
|
||||
perm(
|
||||
"b4b00003-0001-4000-8000-000000000002",
|
||||
"edr_freight_app:settings:invoice_stamp:manage",
|
||||
"Manage invoice stamp settings",
|
||||
"edr_freight_app:settings:teeter:manage",
|
||||
"Manage own approval teeter and signature",
|
||||
),
|
||||
perm(
|
||||
"b4c00001-0001-4000-8000-000000000001",
|
||||
@@ -1907,15 +1913,18 @@ export const FREIGHT_PERMS = {
|
||||
view: "edr_freight_app:settings:dropdown:view",
|
||||
manage: "edr_freight_app:settings:dropdown:manage",
|
||||
},
|
||||
// The ONE company stamp/seal, applied to every generated document
|
||||
// (invoices, receipts, warehouse papers, the EDR side of contracts).
|
||||
stamp: {
|
||||
view: "edr_freight_app:settings:stamp:view",
|
||||
manage: "edr_freight_app:settings:stamp:manage",
|
||||
},
|
||||
// Company stamp/seal image stamped onto invoice/receipt PDFs — separate
|
||||
// from `stamp` above, which is the per-employee approval-record teeter.
|
||||
invoiceStamp: {
|
||||
view: "edr_freight_app:settings:invoice_stamp:view",
|
||||
manage: "edr_freight_app:settings:invoice_stamp:manage",
|
||||
// The per-officer approval teeter (ማህተም) + signature — genuinely per-person,
|
||||
// and NOT the company seal above. Retired: `invoiceStamp`, which used to
|
||||
// gate the company stamp before the two were untangled.
|
||||
teeter: {
|
||||
view: "edr_freight_app:settings:teeter:view",
|
||||
manage: "edr_freight_app:settings:teeter:manage",
|
||||
},
|
||||
exchangeRate: {
|
||||
view: "edr_freight_app:settings:exchange_rate:view",
|
||||
|
||||
@@ -796,7 +796,7 @@ const App = () => {
|
||||
path="stamp-settings"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.settings.invoiceStamp.view}
|
||||
permission={FREIGHT_PERMS.settings.stamp.view}
|
||||
>
|
||||
<CompanyStampSettingsPage />
|
||||
</RequirePermission>
|
||||
|
||||
@@ -493,7 +493,7 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
|
||||
label: "Company stamp",
|
||||
href: "/dashboard/stamp-settings",
|
||||
icon: <Stamp />,
|
||||
permission: FREIGHT_PERMS.settings.invoiceStamp.view,
|
||||
permission: FREIGHT_PERMS.settings.stamp.view,
|
||||
},
|
||||
{
|
||||
label: "Contract templates",
|
||||
|
||||
@@ -328,15 +328,18 @@ export const FREIGHT_PERMS = {
|
||||
view: "edr_freight_app:settings:dropdown:view",
|
||||
manage: "edr_freight_app:settings:dropdown:manage",
|
||||
},
|
||||
// The ONE company stamp/seal, applied to every generated document
|
||||
// (invoices, receipts, warehouse papers, the EDR side of contracts).
|
||||
stamp: {
|
||||
view: "edr_freight_app:settings:stamp:view",
|
||||
manage: "edr_freight_app:settings:stamp:manage",
|
||||
},
|
||||
// Company stamp/seal image stamped onto invoice/receipt PDFs — separate
|
||||
// from `stamp` above, which is the per-employee approval-record teeter.
|
||||
invoiceStamp: {
|
||||
view: "edr_freight_app:settings:invoice_stamp:view",
|
||||
manage: "edr_freight_app:settings:invoice_stamp:manage",
|
||||
// The per-officer approval teeter (ማህተም) + signature — genuinely per-person,
|
||||
// and NOT the company seal above. Retired: `invoiceStamp`, which used to
|
||||
// gate the company stamp before the two were untangled.
|
||||
teeter: {
|
||||
view: "edr_freight_app:settings:teeter:view",
|
||||
manage: "edr_freight_app:settings:teeter:manage",
|
||||
},
|
||||
exchangeRate: {
|
||||
view: "edr_freight_app:settings:exchange_rate:view",
|
||||
|
||||
@@ -147,13 +147,17 @@ export function UserManagementRoutes(): ReactElement {
|
||||
(am/en) and genuinely per-person. It used to sit at
|
||||
/dashboard/stamp-settings under Settings, next to the
|
||||
single global company stamp, which read as duplication.
|
||||
Permission gate unchanged from that route.
|
||||
|
||||
Gated by settings:teeter:*, split out of settings:stamp:*
|
||||
when the two were untangled — settings:stamp:* now means
|
||||
the company stamp, so anyone who held it for the teeter
|
||||
needs the new key granted.
|
||||
*/}
|
||||
<Route
|
||||
path="user-management/teeter-and-signature"
|
||||
element={
|
||||
<RequirePermission
|
||||
permission={FREIGHT_PERMS.settings.stamp.view}
|
||||
permission={FREIGHT_PERMS.settings.teeter.view}
|
||||
>
|
||||
<UploadTeeterAndSignature />
|
||||
</RequirePermission>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { Injectable, Logger, NestMiddleware } from "@nestjs/common";
|
||||
import { Injectable, NestMiddleware } from "@nestjs/common";
|
||||
|
||||
import {
|
||||
RequestLogContext,
|
||||
@@ -58,8 +58,6 @@ const userId = (req: LoggedRequest): string | undefined => {
|
||||
*/
|
||||
@Injectable()
|
||||
export class RequestLogMiddleware implements NestMiddleware {
|
||||
private readonly logger = new Logger("HTTP");
|
||||
|
||||
use(req: LoggedRequest, res: LoggedResponse, next: () => void): void {
|
||||
const start = Date.now();
|
||||
const requestId = header(req, "x-request-id") ?? randomUUID();
|
||||
@@ -85,8 +83,6 @@ export class RequestLogMiddleware implements NestMiddleware {
|
||||
const status = res.statusCode;
|
||||
const durationMs = Date.now() - start;
|
||||
|
||||
this.logger.log(`${req.method} ${url} ${status} ${durationMs}ms`);
|
||||
|
||||
const line = {
|
||||
...ctx,
|
||||
// Fields the Nest console prefix used to carry. They are IN the JSON
|
||||
|
||||
Reference in New Issue
Block a user