Taryana
Branch RBAC & Step FlowEnterprise ERP & Governance
TESTER READY • LIVE ENGINE

Multi-Tenant Branch & Multi-Level Approval Engine

Role-Based Access Control (RBAC) & Step-by-Step Approval Pipeline

Pemisahan data operasional antar cabang regional ISP berbasis Role-Based Access Control (RBAC) & Scoped Tenant Guard serta pipeline persetujuan multi-level otomatis (Sales -> NOC Kelayakan -> Finance Margin -> Dispatch).

Diagram Alur Data & Arsitektur Sistem

Visual Interaktif

Arsitektur Isolasi Cabang RBAC & Pipeline Persetujuan Multi-Level

Isolasi data berbasis Role-Based Access Control (RBAC) dan workflow persetujuan bertingkat

client
JKT-SEL

Regional Branch

Sales / CS Cabang

HTTP with Branch JWT
guard
RBAC Isolation

RBAC Guard

Verify Roles & Branch Scope

Enforce Branch RBAC Scope
db
Zero-Leak

PostgreSQL Engine

Scoped Branch Queries

Advance approval state
service
State Machine

Workflow Engine

Step: NOC -> Finance

All levels approved
device
SPK Approved

HQ Dispatch

Ready for Field Execution

Problem & Latar Belakang Kebutuhan

ISP dengan puluhan kantor cabang regional (misal: Cabang Jakarta Selatan, Bandung, Surabaya) membutuhkan isolasi data ketat agar staf cabang tidak dapat mengakses data pelanggan atau pendapatan cabang lain, sekaligus memerlukan alur persetujuan terpadu untuk permintaan diskon paket khusus atau perubahan rute kabel FO utama.

Implementasi Branch RBAC Guard & Workflow State Machine di NestJS

Setiap request HTTP NestJS diverifikasi hak aksesnya melalui RBAC Guard dan Branch Scoped Interceptor. NestJS mengevaluasi peran pengguna (Superadmin, Branch Manager, NOC Engineer, Finance Lead) dan mengunci query database ke branch_id yang berwenang. Approval engine mengimplementasikan state machine terdistribusi di mana setiap transisi status memerlukan hak akses peran pengguna (RBAC) yang terverifikasi.

Aspek Role-Based Access Control (RBAC) & Branch Tenant Isolation

Tabel-tabel inti menerapkan constraint foreign key branch_id terindeks dengan scoped repository wrapper di NestJS: query otomatis mengikat branch_id sesuai klaim token JWT pengguna, kecuali bagi peran Superadmin HQ yang memiliki hak akses global lintas cabang.

Keamanan, Idempotensi & Kepatuhan SLA

Mencegah cross-branch data breach secara mendasar melalui verifikasi token JWT bertingkat yang mengikat klaim branch_id dan hierarki peran (Branch Manager, Area Lead, HQ Superadmin).

NestJS BranchRbacGuard & Workflow EngineNestJS (TypeScript) / RBAC Guard
// Branch RBAC Guard & Multi-Level Approval Engine di NestJS
@Injectable()
export class BranchRbacGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredRoles = this.reflector.getAllAndOverride<string[]>('roles', [
      context.getHandler(),
      context.getClass(),
    ]);
    const request = context.switchToHttp().getRequest();
    const user = request.user;

    if (!user || !user.branchId) {
      throw new UnauthorizedException('Konteks cabang dan kredensial pengguna tidak valid');
    }

    // Superadmin HQ memiliki akses bypass lintas cabang
    if (user.role === 'superadmin') return true;

    // Validasi izin peran (RBAC)
    if (requiredRoles && !requiredRoles.includes(user.role)) {
      throw new ForbiddenException('Akses ditolak: peran Anda tidak berwenang mengeksekusi aksi cabang ini');
    }

    return true;
  }
}

@Injectable()
export class OrderApprovalWorkflowService {
  constructor(@InjectRepository(ServiceOrder) private orderRepo: Repository<ServiceOrder>) {}

  async advanceApprovalStep(orderId: string, user: AuthenticatedUser, step: 'NOC' | 'FINANCE'): Promise<ServiceOrder> {
    const order = await this.orderRepo.findOneBy({ id: orderId });
    if (!order) throw new NotFoundException('SPK Order tidak ditemukan');

    if (step === 'NOC') {
      if (user.role !== 'noc_engineer') throw new ForbiddenException('Hanya NOC yang berwenang approve kelayakan fiber');
      order.nocApprovedAt = new Date();
      order.status = 'NOC_VERIFIED';
    } else if (step === 'FINANCE') {
      if (user.role !== 'finance_lead') throw new ForbiddenException('Hanya Finance yang berwenang approve diskon');
      order.financeApprovedAt = new Date();
      order.status = 'READY_FOR_DISPATCH';
    }

    return this.orderRepo.save(order);
  }
}

Live Simulator & Execution Sandbox

Interactive State Tester
Role-Based Access Control (RBAC):Enforcing Branch Scope: 'JKT-SEL'Isolasi data 100% via RBAC Guard. Staf cabang lain tidak dapat melihat antrian SPK cabang ini.
Execution Telemetry Console
HTTP 200 OK
POST/api/v1/network/coverage/check
> Guard Evaluation Trace:

PostGIS GiST R-Tree ST_DWithin query executed in 3.8ms. Matched ODP-FATMAWATI-42 (84.2m).

> Database & State Result:

Estimated optical attenuation: -17.4 dBm. Port 4 of 8 available. Redis lock acquired with 24h TTL.

Audit Trail PostgreSQL & Redis (2 events)Auto-Appended
[10:14:02]SETTLEMENT(Double-Entry Worker)•WEBHOOK_INVOICE_SETTLED

HMAC-SHA256 verified. Redis Redlock acquired. Invoice INV-2026-0982 settled with zero ledger variance.

SUCCESS
[10:22:15]POSTGIS(Coverage Engine (NestJS))•ODP_PORT_RESERVED

ST_DWithin R-Tree matched ODP in 4.1ms (dist: 84.2m). Optical loss -17.4 dBm. Splitter port locked with 24h Redis TTL.

SUCCESS