Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Broker Collections & Policy Cockpit

A local-first SAP Fiori-style insurance cockpit built for a portfolio targeting an SAP Fiori Developer role.

The app demonstrates how a broker can manage policies, overdue premium items, claims, commissions, reminders, and follow-up tasks in one workflow-driven UI built with OpenUI5 and SAP CAP.

It is intentionally scoped as a polished MVP:

  • free to run locally
  • no SAP BTP account required
  • no Docker required
  • realistic insurance terminology and sample data
  • OData V4 backend + freestyle UI5 frontend

Why this project exists

Insurance brokers often work across disconnected spreadsheets, insurer portals, and back-office systems. That makes it hard to answer practical questions quickly:

  • Which premium items are overdue today?
  • Which customers need follow-up?
  • Which claims are waiting on documents or insurer action?
  • How much commission is expected from paid premium?

This project packages those daily broker tasks into one Fiori-style cockpit with a clean UI, clear semantic statuses, and realistic actions.

What this project focuses on

This repository focuses on a realistic insurance operations scenario implemented with SAP-style full-stack patterns:

  • UI5 MVC application structure
  • multi-page routing and shell navigation
  • OData V4 integration
  • CDS-based domain modeling
  • business actions for collections and claims workflows
  • testing and documentation

Business scenario

The core demo flow is:

  1. The broker opens the dashboard and sees overdue open items and claims needing attention.
  2. The broker navigates to Open Items and filters for overdue receivables.
  3. The broker opens the related policy context and registers a payment.
  4. The open item status updates from Open or Overdue to Partially Paid or Paid.
  5. The backend recalculates commission based on premium collected.
  6. The broker creates a reminder or a follow-up task from the same process.

That flow is intentionally close to real insurance collections work, while still being small enough to run locally as a portfolio project.

What the app includes

Dashboard

  • KPI cards for:
    • Active Policies
    • Overdue Open Items
    • Total Outstanding Amount
    • Open Claims
    • Expected Commission
  • recent overdue open items table
  • claims requiring attention table
  • analytics tiles for portfolio distribution and operational status

Policies

  • searchable list/report-style page
  • filters by policy type and status
  • broker/customer context
  • navigation to a dedicated detail page

Policy Detail

  • object-page style detail view
  • general policy information
  • related open items
  • related claims
  • related commissions
  • related tasks and reminders

Open Items

  • the main collections workspace
  • receivables list with status and overdue visibility
  • actions:
    • Mark as Paid
    • Register Partial Payment
    • Create Reminder
    • Create Follow-up Task

Claims

  • claim tracking table
  • staged workflow progression
  • close/reject action

Commissions

  • expected vs paid commission visibility
  • broker-oriented earnings overview

Tech stack

Layer Technology Why it was chosen
Backend Node.js Simple, common JavaScript runtime
Service layer SAP CAP Fast way to model domain entities, expose OData, and add business actions
Data model CDS (schema.cds, service projections) Clean SAP-style modeling and readable domain structure
Database SQLite Free, lightweight, easy to seed locally
Frontend OpenUI5 freestyle app Demonstrates SAPUI5-style frontend skills without requiring paid SAP setup
UI architecture MVC with XML Views Standard UI5 project structure recruiters expect to see
Data access OData V4 model Strong SAP relevance; clean list/detail/action integration
Testing Jest, QUnit Backend logic coverage + formatter coverage
Styling Standard UI5 controls + custom CSS Fiori-like look while keeping the app realistic and lightweight

Architecture overview

flowchart LR
    U["Browser"] --> UI["OpenUI5 Freestyle App<br/>app/webapp"]
    UI --> ROUTER["UI5 Router<br/>manifest.json"]
    ROUTER --> VIEWS["XML Views + Controllers"]
    VIEWS --> ODATA["OData V4 Model"]
    ODATA --> CAP["SAP CAP Service<br/>srv/broker-service.cds<br/>srv/broker-service.js"]
    CAP --> CDS["CDS Domain Model<br/>db/schema.cds"]
    CAP --> DB["SQLite<br/>db.sqlite"]
    DB --> CSV["CSV Seed Data<br/>db/data/*.csv"]
Loading

Solution architecture, in plain language

The application is split into two clear parts:

1. UI layer

The frontend lives under app/webapp and is a freestyle OpenUI5 application.

It uses:

  • Component.js to bootstrap the app and initialize routing
  • manifest.json to define models, routes, and dependencies
  • XML Views for page layout
  • Controllers for page behavior and user actions
  • a formatter module for UI-specific logic such as value-state mapping and overdue calculation

2. Service and persistence layer

The backend lives in:

  • db/schema.cds
  • srv/broker-service.cds
  • srv/broker-service.js

CAP handles:

  • entity exposure as OData V4
  • projections for frontend-friendly fields like customerName
  • action endpoints for business workflows
  • SQLite integration
  • CSV seeding

Project structure

broker-cockpit/
├─ app/
│  ├─ index.html
│  └─ webapp/
│     ├─ Component.js
│     ├─ manifest.json
│     ├─ controller/
│     ├─ view/
│     ├─ model/
│     ├─ fragment/
│     ├─ i18n/
│     ├─ css/
│     └─ test/
├─ db/
│  ├─ schema.cds
│  └─ data/
├─ srv/
│  ├─ broker-service.cds
│  ├─ broker-service.js
│  └─ broker-service.test.js
├─ package.json
└─ README.md

Data model overview

The domain model is intentionally business-readable. Policies sit at the center, with operational entities around them.

Main entities

  • Customers
  • Brokers
  • Policies
  • Installments
  • OpenItems
  • Payments
  • Claims
  • Commissions
  • Reminders
  • Tasks

ER diagram

erDiagram
    CUSTOMERS ||--o{ POLICIES : owns
    BROKERS ||--o{ POLICIES : manages
    POLICIES ||--o{ INSTALLMENTS : has
    POLICIES ||--o{ OPENITEMS : has
    OPENITEMS ||--o{ PAYMENTS : receives
    OPENITEMS ||--o{ REMINDERS : triggers
    POLICIES ||--o{ CLAIMS : has
    POLICIES ||--o{ COMMISSIONS : generates
    POLICIES ||--o{ TASKS : creates
    OPENITEMS ||--o{ TASKS : relates_to

    CUSTOMERS {
        UUID ID PK
        String firstName
        String lastName
        String email
        String city
        String country
    }

    BROKERS {
        UUID ID PK
        String name
        String licenseNo
        Decimal commRate
        String email
    }

    POLICIES {
        UUID ID PK
        String policyNumber
        String policyType
        String status
        Date startDate
        Date endDate
        Decimal annualPremium
        String currency
    }

    OPENITEMS {
        UUID ID PK
        Date dueDate
        Decimal amount
        Decimal paidAmount
        String status
        String currency
        String description
    }

    PAYMENTS {
        UUID ID PK
        Date paymentDate
        Decimal amount
        String method
        String reference
    }

    CLAIMS {
        UUID ID PK
        String claimNumber
        String claimType
        String status
        Date reportedDate
        Decimal estimatedAmount
        Decimal paidAmount
    }

    COMMISSIONS {
        UUID ID PK
        Decimal premiumPaid
        Decimal commRate
        Decimal expectedAmount
        Decimal paidAmount
        String status
    }

    REMINDERS {
        UUID ID PK
        DateTime reminderDate
        String note
        Boolean sent
    }

    TASKS {
        UUID ID PK
        String title
        String description
        Date dueDate
        Boolean done
        String priority
    }

    INSTALLMENTS {
        UUID ID PK
        Integer installmentNo
        Date dueDate
        Decimal amount
        Boolean paid
    }
Loading

Sample data

The app is preloaded with demo data to make the UI feel like a real working portfolio, not an empty skeleton.

The dataset includes:

  • 8 customers
  • 2 brokers
  • 15 policies
  • multiple policy types:
    • Motor
    • Property
    • Life
    • Travel
    • Health
  • open items in different states:
    • Open
    • Partially Paid
    • Paid
    • Overdue
    • In Dispute
  • claims in different stages
  • commission records
  • reminders and tasks

Default currency is EUR.

OData V4 design

This project uses CAP to expose a clean OData V4 service at:

/odata/v4/broker/

Why OData V4 matters here

OData V4 is relevant for SAP frontend work because it gives the UI a standard way to:

  • read lists and details
  • expand related entities
  • filter and sort on the server
  • trigger business actions through defined endpoints
  • stay close to enterprise SAP app patterns

That makes this project much more SAP-relevant than a generic REST-only demo.

Exposed entity sets

The service exposes frontend-facing projections for:

  • Customers
  • Brokers
  • Policies
  • Installments
  • OpenItems
  • Payments
  • Claims
  • Commissions
  • Reminders
  • Tasks

Several projections also include convenience fields for UI consumption, for example:

  • customerName
  • policyNumber
  • policyType
  • brokerName

This keeps the UI simpler while still preserving a proper normalized backend model.

OData read patterns used in the UI

The UI relies on standard OData query options such as:

  • $select to limit payload fields
  • $expand to load related customer, policy, or broker context
  • $orderby to sort lists like overdue items and claims
  • $filter for page filters such as policy status or open item status

Examples used in practice:

/Policies?$orderby=policyNumber asc&$expand=customer($select=firstName,lastName),broker($select=name)
/OpenItems?$orderby=dueDate asc&$expand=policy($select=policyNumber,policyType),customer($select=firstName,lastName)
/Claims?$orderby=reportedDate desc

OData actions and function

The backend also exposes business operations beyond plain reads.

Actions

  • markAsPaid(openItemId)
  • registerPartialPayment(openItemId, amount, paymentDate)
  • createReminder(openItemId, note, reminderDate)
  • createFollowUpTask(openItemId, title, dueDate)
  • moveClaimToNextStatus(claimId)
  • closeClaim(claimId, note)
  • calculateCommission(policyId)

These actions are called from the UI when a broker performs operational work from tables or dialogs.

Function

  • getDashboardKPIs()

This function returns aggregated dashboard values:

  • active policies
  • overdue open items
  • total outstanding amount
  • open claims
  • expected commission

Business logic behind the OData actions

The logic in srv/broker-service.js is the operational core of the project.

Open item settlement logic

For each open item:

  • outstandingAmount = amount - paidAmount
  • if outstanding becomes 0, status becomes Paid
  • if some money is paid but balance remains, status becomes PartiallyPaid
  • if the due date is in the past and the item is not fully settled, it is operationally treated as overdue

Payment registration

When a payment is registered:

  1. a Payment record is created
  2. the OpenItem paidAmount is updated
  3. the OpenItem status is recalculated
  4. commission is recalculated for the related policy

Commission logic

Commission is derived from collected premium, not just nominal premium.

The service:

  • sums paid amounts from paid/partially paid open items for a policy
  • applies the broker commission rate
  • updates the commission record

Claims workflow logic

Claims move through a simple controlled sequence:

New → WaitingDocuments → SentToInsurer → Approved → Paid

The closeClaim action marks a claim as rejected/closed with a note.

Frontend architecture

UI shell

The app is structured around a UI5 shell with route-driven navigation. Main building blocks include:

  • Component.js
  • manifest.json
  • App.view.xml
  • per-page controllers and views

UI patterns used

  • MVC architecture
  • XML Views
  • controller-based event handling
  • reusable fragments for dialogs
  • i18n resource bundle
  • semantic ObjectStatus
  • ObjectNumber for financial values
  • message toasts and message boxes for user feedback
  • busy indicators during backend operations

Important frontend files

  • app/webapp/Component.js
  • app/webapp/manifest.json
  • app/webapp/controller/
  • app/webapp/view/
  • app/webapp/model/formatter.js

Backend architecture

CDS model

The CDS model defines:

  • domain entities
  • associations and compositions
  • enum-like status types for insurance objects

This gives the project a very SAP-style, readable backend foundation.

Service layer

The service layer has two files:

  • srv/broker-service.cds for the OData contract
  • srv/broker-service.js for behavior

That split is useful in a portfolio because it clearly shows:

  • data model
  • exposed API
  • business logic

How to run locally

Prerequisites

  • Node.js 18 or newer
  • npm 9 or newer

Install

cd "C:\Users\DELL\SAP Fioneer\broker-cockpit"
npm install

Seed the SQLite database

npx cds deploy --to sqlite

Or reset and reseed in one command:

npm run reset-db

Start the app

npm run watch

Local URLs

URL Purpose
http://localhost:4004/ CAP launch page
http://localhost:4004/webapp/index.html Main UI5 application
http://localhost:4004/odata/v4/broker/ OData V4 service root
http://localhost:4004/odata/v4/broker/$metadata OData metadata
http://localhost:4004/webapp/test/unit/unitTests.qunit.html QUnit test page

Useful npm scripts

Command What it does
npm install installs project dependencies
npm run watch starts CAP with live reload for development
npm start starts the service without watch mode
npm test runs backend Jest tests
npm run reset-db deletes and recreates the SQLite database from CSV seed data

Deployment status

This project is designed first as a local-first portfolio application.

Deployment update

The current Vercel deployment is fully working for demo use:

Hosted limitation:

  • the deployed environment uses in-memory SQLite
  • data can reset between cold starts
  • the local setup remains the primary persistent development environment

Earlier deployment note

The note below reflects an earlier stage of the deployment work before the Vercel runtime fixes were completed.

A Vercel deployment was created during development at:

Important limitation

The Vercel deployment currently serves the frontend successfully, but the full CAP + SQLite backend is not working correctly in Vercel’s serverless runtime for this setup.

That means:

  • the UI can be opened
  • static frontend assets are served
  • the OData V4 backend is not fully operational in that environment
  • the Vercel link should be treated as a frontend preview, not as the final full-stack production deployment

Why this happens

The app uses:

  • SAP CAP
  • SQLite
  • OData V4
  • runtime-loaded CAP service infrastructure

That combination works well locally, but it is not an ideal fit for Vercel’s serverless function packaging model in this project shape. During deployment, CAP’s SQLite runtime resolution and related backend packaging behavior cause the OData service startup to fail even though the same code works locally.

Recommended production-style hosting target

For a real full-stack public deployment of this repository, a better fit would be a host that runs a normal long-lived Node.js server process, for example:

  • Render
  • Railway
  • Fly.io

Those platforms are a better match for:

  • CAP service bootstrapping
  • SQLite or alternative attached databases
  • stateful backend actions
  • a complete end-to-end portfolio demo link

Testing

The project includes both frontend-oriented and backend-oriented tests so the repo demonstrates more than just UI implementation.

QUnit

QUnit is used for lightweight frontend unit testing in the UI5 app.

In this project, QUnit is used to validate presentation and helper logic from the formatter layer, which is a common place for UI-specific business rules in UI5 applications.

The QUnit tests cover logic such as:

  • semantic status-to-state mapping for ObjectStatus
  • outstanding amount calculation
  • overdue day calculation
  • visibility logic for paid vs unpaid records

Why that matters:

  • it shows how UI behavior can be tested without relying on manual browser checks
  • it keeps small but important business-display rules from silently breaking
  • it reflects a realistic UI5 testing entry point for a portfolio project

The QUnit entry page is:

http://localhost:4004/webapp/test/unit/unitTests.qunit.html

OPA5

OPA5 is UI5’s browser-based integration testing approach for end-to-end user journeys.

In this repository, an OPA5 smoke-test scaffold is included as a starting point. It is not yet a full regression suite, but it demonstrates the intended testing direction for UI interactions such as:

  • launching the application
  • navigating between pages
  • selecting list items
  • executing business actions
  • verifying UI state changes after backend calls

Why OPA5 is relevant here:

  • it is SAP-native UI test tooling
  • it maps naturally to business workflows rather than isolated functions
  • it is especially useful for validating routing, dialogs, and table-driven interactions in UI5 apps

This project currently includes the scaffold so the repository stays practical in scope while still showing awareness of the right UI5 integration-test pattern.

Backend

Jest tests cover the CAP service contract and core business actions, including:

  • entity-set reads
  • dashboard KPI function
  • payment action logic
  • claim workflow progression

Demo scenario for recruiters or interviews

If you want to present the project quickly, this is the best walkthrough:

  1. Open the dashboard and explain the broker use case.
  2. Point out overdue open items and claims requiring attention.
  3. Navigate to Open Items.
  4. Filter by Overdue.
  5. Select one item and register a partial payment.
  6. Show the status update and explain the payment/business logic.
  7. Create a reminder or a follow-up task.
  8. Navigate to Claims and move one claim to the next status.
  9. Open Policies and drill into a policy detail page.
  10. Close with the commission overview and the CAP/OData architecture.

Screenshots

Add screenshots here once you are happy with the final UI.

  • Dashboard
  • Policies
  • Policy Detail
  • Open Items
  • Claims
  • Commissions

Known limitations

  • no authentication or authorization layer yet
  • no SAP BTP deployment target configured in this repo
  • no real email or reminder delivery
  • dashboard KPI aggregation is intentionally lightweight for local SQLite use
  • OPA5 coverage is scaffold-level, not full journey coverage

Recommended next improvements

  • add full OPA5 journeys for the main broker workflow
  • improve dashboard charts and analytical interactions
  • add date-range filters on open items and claims
  • introduce role-based broker views
  • add export options for operational reporting
  • add Fiori Launchpad sandbox configuration
  • migrate demo persistence to SAP HANA Cloud for a cloud-hosted version

Why this project is relevant for an SAP Fiori Developer application

This project is strong as a portfolio piece because it shows both sides of the typical SAP full-stack workflow:

  • a UI5 frontend organized the way SAP teams expect
  • a CAP backend with CDS and OData V4
  • business-focused enterprise UX rather than a generic CRUD toy
  • local reproducibility for reviewers
  • enough domain complexity to talk through real implementation choices

It is especially useful for a candidate with insurance-domain experience because it connects that domain knowledge to SAP-style technical delivery.

About

Local-first SAP Fiori-style insurance broker cockpit built with OpenUI5, SAP CAP, SQLite, and OData V4.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages