Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ export const ControlPostureDashboard: Dashboard = {
values: ['assessment_count'],
title: 'Assessments Completed by Month (last 12 months)',
type: 'line',
// "Completed" = any concluded assessment. There is no `complete` status;
// the real terminal results are passed / partial / failed.
filter: {
status: 'complete',
status: { $in: ['passed', 'partial', 'failed'] },
assessed_at: { $gte: '{12_months_ago}' },
},
compareTo: 'previousYear',
Expand Down
33 changes: 33 additions & 0 deletions packages/compliance/src/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ const frameworks = defineSeed(Framework, {
version: '2016',
status: 'active',
},
{
short_name: 'HIPAA',
full_name: 'HIPAA Security Rule — 45 CFR Part 164 Subpart C',
family: 'hipaa',
version: '2013',
status: 'active',
next_audit_date: cel`daysFromNow(210)`,
},
],
});

Expand Down Expand Up @@ -117,6 +125,29 @@ const controls = defineSeed(Control, {
description:
'Appropriate technical & organisational measures to ensure security of personal data. Past review-frequency window.',
},
{
code: '164.308(a)(1)',
title: 'Security Management Process',
framework: 'HIPAA',
category: 'risk',
criticality: 'high',
last_status: 'passed',
review_frequency_days: 365,
last_assessed_at: cel`daysAgo(40)`,
description:
'Implement policies to prevent, detect, contain, and correct security violations (risk analysis + risk management).',
},
{
code: '164.312(a)(1)',
title: 'Access Control (ePHI)',
framework: 'HIPAA',
category: 'access',
criticality: 'high',
last_status: 'not_tested',
review_frequency_days: 180,
description:
'Technical policies allowing only authorized persons to access electronic protected health information.',
},
],
});

Expand Down Expand Up @@ -206,6 +237,7 @@ const assessments = defineSeed(Assessment, {
status: 'failed',
finding: 'Two high-severity CVEs open past 30-day SLA on edge servers.',
remediation_plan: 'Patch edge servers in next maintenance window (2026-04-15).',
remediation_status: 'open',
remediation_due: cel`daysFromNow(14)`,
},
{
Expand All @@ -216,6 +248,7 @@ const assessments = defineSeed(Assessment, {
status: 'partial',
finding: '3 of 25 PRs sampled lacked documented reviewer.',
remediation_plan: 'Enforce required-reviewer via repo settings; re-test in Q2.',
remediation_status: 'in_progress',
remediation_due: cel`daysFromNow(30)`,
},
{
Expand Down
19 changes: 17 additions & 2 deletions packages/compliance/src/objects/compliance_assessment.object.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2026 ObjectStack contributors. Apache-2.0 license.

import { ObjectSchema, Field } from '@objectstack/spec/data';
import { P, tmpl } from '@objectstack/spec';
import { P, F, tmpl } from '@objectstack/spec';
/**
* Assessment — a discrete test of a control. Each control should have
* one per `review_frequency_days`. Result rolls up onto Control.last_status.
Expand Down Expand Up @@ -52,7 +52,22 @@ export const Assessment = ObjectSchema.create({
label: 'Remediation Plan',
description: 'Required when status is failed or partial.',
}),
remediation_status: Field.select({
label: 'Remediation Status',
description: 'Tracks the fix for a failed/partial finding to closure.',
options: [
{ label: 'Open', value: 'open', color: '#EF4444' },
{ label: 'In Progress', value: 'in_progress', color: '#F59E0B' },
{ label: 'Resolved', value: 'resolved', color: '#10B981' },
{ label: 'Risk Accepted', value: 'risk_accepted', color: '#6B7280' },
],
}),
remediation_due: Field.date({ label: 'Remediation Due' }),
is_remediation_overdue: Field.formula({
label: 'Remediation Overdue',
description: 'Past the remediation due date and not yet resolved / risk-accepted.',
expression: F`record.remediation_due != null && record.remediation_due < today() && record.remediation_status != "resolved" && record.remediation_status != "risk_accepted"`,
}),
},

enable: {
Expand All @@ -74,7 +89,7 @@ export const Assessment = ObjectSchema.create({
],

titleFormat: tmpl`{{record.title}}`,
compactLayout: ['title', 'control', 'status', 'cycle', 'assessed_at'],
compactLayout: ['title', 'control', 'status', 'remediation_status', 'cycle', 'assessed_at'],

validations: [
{
Expand Down
13 changes: 11 additions & 2 deletions packages/compliance/src/translations/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,22 @@ export const en: TranslationData = {
},
finding: { label: 'Finding' },
remediation_plan: { label: 'Remediation Plan' },
remediation_status: {
label: 'Remediation Status',
options: {
open: 'Open',
in_progress: 'In Progress',
resolved: 'Resolved',
risk_accepted: 'Risk Accepted',
},
},
remediation_due: { label: 'Remediation Due' },
is_remediation_overdue: { label: 'Remediation Overdue' },
},
_views: {
all_assessments: { label: 'All Assessments' },
failed_assessments: { label: 'Failed Assessments' },
open_remediations: { label: 'Open Remediations' },
in_progress_assessments: { label: 'In Progress' },
},
},
Expand Down Expand Up @@ -229,8 +240,6 @@ export const en: TranslationData = {
title: 'Assessments In Progress',
description: 'Assessments currently being conducted',
},
failing_table: { title: 'Failing Controls (Action Required)' },
expiring_evidence_table: { title: 'Evidence Expiring Soon' },
},
},
},
Expand Down
13 changes: 11 additions & 2 deletions packages/compliance/src/translations/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,22 @@ export const zhCN: TranslationData = {
},
finding: { label: '审计发现' },
remediation_plan: { label: '整改计划' },
remediation_status: {
label: '整改状态',
options: {
open: '待整改',
in_progress: '整改中',
resolved: '已整改',
risk_accepted: '接受风险',
},
},
remediation_due: { label: '整改截止' },
is_remediation_overdue: { label: '整改逾期' },
},
_views: {
all_assessments: { label: '全部评估' },
failed_assessments: { label: '未通过评估' },
open_remediations: { label: '待整改项' },
in_progress_assessments: { label: '进行中' },
},
},
Expand Down Expand Up @@ -203,8 +214,6 @@ export const zhCN: TranslationData = {
failing_controls: { title: '未通过或部分通过' },
expiring_evidence: { title: '30 天内到期佐证' },
in_progress_assessments: { title: '进行中评估' },
failing_table: { title: '需整改的控制项' },
expiring_evidence_table: { title: '即将到期的佐证' },
},
},
},
Expand Down
26 changes: 25 additions & 1 deletion packages/compliance/src/views/compliance_assessment.view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ export const AssessmentViews = defineView({
tabs: [
{ name: 'all', label: 'All', view: 'all_assessments', isDefault: true, pinned: true },
{ name: 'failed', label: 'Failed', icon: 'alert-triangle', view: 'failed_assessments' },
{
name: 'open_remediations',
label: 'Open Remediations',
icon: 'wrench',
view: 'open_remediations',
},
{ name: 'in_progress', label: 'In Progress', icon: 'play', view: 'in_progress_assessments' },
],
},
Expand All @@ -39,6 +45,16 @@ export const AssessmentViews = defineView({
sort: [{ field: 'remediation_due', order: 'asc' }],
},

open_remediations: {
name: 'open_remediations',
type: 'grid',
label: 'Open Remediations',
data: { provider: 'object', object: 'compliance_assessment' },
columns: ['title', 'control', 'remediation_status', 'remediation_due', 'assessor'],
filter: [{ field: 'remediation_status', operator: 'in', value: ['open', 'in_progress'] }],
sort: [{ field: 'remediation_due', order: 'asc' }],
},

in_progress_assessments: {
name: 'in_progress_assessments',
type: 'grid',
Expand Down Expand Up @@ -67,7 +83,15 @@ export const AssessmentViews = defineView({
],
},
{ label: 'Finding', columns: 1, fields: ['finding'] },
{ label: 'Remediation', columns: 2, fields: ['remediation_due', 'remediation_plan'] },
{
label: 'Remediation',
columns: 2,
fields: [
'remediation_status',
'remediation_due',
{ field: 'remediation_plan', colSpan: 2 },
],
},
],
},
});
Loading