fix payment customer and dashboard settings
Build & Deploy / Build & Push Docker Image (push) Successful in 12m39s
Test / Type Check (all packages) (push) Successful in 5m8s
Build & Deploy / Deploy to VPS (push) Successful in 7s
Test / API Unit Tests (push) Failing after 4m24s
Test / Homepage Unit Tests (push) Successful in 3m27s
Test / Storefront Unit Tests (push) Successful in 4m48s
Test / Admin Unit Tests (push) Successful in 3m0s
Test / Dashboard Unit Tests (push) Successful in 4m18s
Test / API Integration Tests (push) Failing after 4m34s

This commit is contained in:
root
2026-06-29 22:15:34 -04:00
parent e1e2f55c93
commit a752a399c2
30 changed files with 4503 additions and 1214 deletions
@@ -8,6 +8,12 @@ import { parseBody, parseParams } from '../../http/validate'
import { ok, created, noContent } from '../../http/respond'
import { imageUpload, assertImageFile } from '../../http/upload'
import * as service from './company.service'
import {
normalizeSettingsLocale,
requireSettingsFeature,
resolveSettingsEntitlements,
resolveSettingsMenu,
} from './settingsEntitlements'
import {
companySchema, brandSchema, contractSettingsSchema,
insurancePolicySchema, pricingRuleSchema, accountingSettingsSchema,
@@ -40,7 +46,7 @@ router.get('/me/brand', async (req, res, next) => {
} catch (err) { next(err) }
})
router.patch('/me/brand', requireRole('OWNER'), async (req, res, next) => {
router.patch('/me/brand', requireRole('OWNER'), requireSettingsFeature('settings.branding_basic'), async (req, res, next) => {
try {
const body = parseBody(brandSchema, req)
const brand = await service.updateBrand(req.companyId, body, req.company.name, req.company.slug)
@@ -48,7 +54,7 @@ router.patch('/me/brand', requireRole('OWNER'), async (req, res, next) => {
} catch (err) { next(err) }
})
router.post('/me/brand/logo', requireRole('OWNER'), imageUpload.single('file'), async (req, res, next) => {
router.post('/me/brand/logo', requireRole('OWNER'), requireSettingsFeature('settings.branding_basic'), imageUpload.single('file'), async (req, res, next) => {
try {
assertImageFile(req.file, 'logo')
const brand = await service.uploadLogo(req.companyId, req.company.name, req.company.slug, req.file.buffer)
@@ -56,7 +62,7 @@ router.post('/me/brand/logo', requireRole('OWNER'), imageUpload.single('file'),
} catch (err) { next(err) }
})
router.post('/me/brand/hero', requireRole('OWNER'), imageUpload.single('file'), async (req, res, next) => {
router.post('/me/brand/hero', requireRole('OWNER'), requireSettingsFeature('settings.branding_hero'), imageUpload.single('file'), async (req, res, next) => {
try {
assertImageFile(req.file, 'hero image')
const brand = await service.uploadHeroImage(req.companyId, req.company.name, req.company.slug, req.file.buffer)
@@ -64,6 +70,18 @@ router.post('/me/brand/hero', requireRole('OWNER'), imageUpload.single('file'),
} catch (err) { next(err) }
})
router.get('/me/settings-menu', async (req, res, next) => {
try {
ok(res, await resolveSettingsMenu(req.companyId, normalizeSettingsLocale(req.query.locale as string | undefined)))
} catch (err) { next(err) }
})
router.get('/me/settings-entitlements', async (req, res, next) => {
try {
ok(res, await resolveSettingsEntitlements(req.companyId))
} catch (err) { next(err) }
})
router.post('/me/brand/subdomain/check', requireRole('OWNER'), async (req, res, next) => {
try {
const { subdomain } = parseBody(subdomainSchema, req)
@@ -101,7 +119,7 @@ router.get('/me/contract-settings', async (req, res, next) => {
} catch (err) { next(err) }
})
router.patch('/me/contract-settings', requireRole('MANAGER'), async (req, res, next) => {
router.patch('/me/contract-settings', requireRole('MANAGER'), requireSettingsFeature('settings.rental_policies_basic'), async (req, res, next) => {
try {
const body = parseBody(contractSettingsSchema, req)
const settings = await service.updateContractSettings(req.companyId, body)
@@ -116,7 +134,7 @@ router.get('/me/insurance-policies', async (req, res, next) => {
} catch (err) { next(err) }
})
router.post('/me/insurance-policies', requireRole('MANAGER'), async (req, res, next) => {
router.post('/me/insurance-policies', requireRole('MANAGER'), requireSettingsFeature('settings.insurance_policies'), async (req, res, next) => {
try {
const body = parseBody(insurancePolicySchema, req)
const policy = await service.createInsurancePolicy(req.companyId, body)
@@ -124,7 +142,7 @@ router.post('/me/insurance-policies', requireRole('MANAGER'), async (req, res, n
} catch (err) { next(err) }
})
router.patch('/me/insurance-policies/:id', requireRole('MANAGER'), async (req, res, next) => {
router.patch('/me/insurance-policies/:id', requireRole('MANAGER'), requireSettingsFeature('settings.insurance_policies'), async (req, res, next) => {
try {
const { id } = parseParams(idParamSchema, req)
const body = parseBody(insurancePolicySchema.partial(), req)
@@ -133,7 +151,7 @@ router.patch('/me/insurance-policies/:id', requireRole('MANAGER'), async (req, r
} catch (err) { next(err) }
})
router.delete('/me/insurance-policies/:id', requireRole('MANAGER'), async (req, res, next) => {
router.delete('/me/insurance-policies/:id', requireRole('MANAGER'), requireSettingsFeature('settings.insurance_policies'), async (req, res, next) => {
try {
const { id } = parseParams(idParamSchema, req)
await service.deleteInsurancePolicy(id, req.companyId)
@@ -148,7 +166,7 @@ router.get('/me/pricing-rules', async (req, res, next) => {
} catch (err) { next(err) }
})
router.post('/me/pricing-rules', requireRole('MANAGER'), async (req, res, next) => {
router.post('/me/pricing-rules', requireRole('MANAGER'), requireSettingsFeature('settings.pricing_rules'), async (req, res, next) => {
try {
const body = parseBody(pricingRuleSchema, req)
const rule = await service.createPricingRule(req.companyId, body)
@@ -156,7 +174,7 @@ router.post('/me/pricing-rules', requireRole('MANAGER'), async (req, res, next)
} catch (err) { next(err) }
})
router.patch('/me/pricing-rules/:id', requireRole('MANAGER'), async (req, res, next) => {
router.patch('/me/pricing-rules/:id', requireRole('MANAGER'), requireSettingsFeature('settings.pricing_rules'), async (req, res, next) => {
try {
const { id } = parseParams(idParamSchema, req)
const body = parseBody(pricingRuleSchema.partial(), req)
@@ -165,7 +183,7 @@ router.patch('/me/pricing-rules/:id', requireRole('MANAGER'), async (req, res, n
} catch (err) { next(err) }
})
router.delete('/me/pricing-rules/:id', requireCompanyPolicy('deletePricingRule'), async (req, res, next) => {
router.delete('/me/pricing-rules/:id', requireCompanyPolicy('deletePricingRule'), requireSettingsFeature('settings.pricing_rules'), async (req, res, next) => {
try {
const { id } = parseParams(idParamSchema, req)
await service.deletePricingRule(id, req.companyId)
@@ -180,7 +198,7 @@ router.get('/me/accounting-settings', async (req, res, next) => {
} catch (err) { next(err) }
})
router.patch('/me/accounting-settings', requireCompanyPolicy('updateAccountingSettings'), async (req, res, next) => {
router.patch('/me/accounting-settings', requireCompanyPolicy('updateAccountingSettings'), requireSettingsFeature('settings.accounting_defaults'), async (req, res, next) => {
try {
const body = parseBody(accountingSettingsSchema, req)
const settings = await service.updateAccountingSettings(req.companyId, body)