Module map

The fractal principle

The project is organised in what its own README calls a fractal architecture: the folder vocabulary repeats at every depth. A module may contain model/, services/, store/, shared/, enums/, pipes/, utils/ and sub-component folders — and a sub-component folder may contain the same set again.

Original structure sketch from the repository README

The placement rule is scope:

Scope of the thing Where it goes

Whole application

src/app/shared/…

One feature module

<module>/shared/…, <module>/services/…, <module>/model/…

One component subtree

Inside that component’s folder

Cross-module state

<module>/store/…, registered in src/app/store/app.reducers.ts

Angular’s "as flat as possible" guidance is deliberately not followed; the folder tree is meant to mirror the business and UI structure. See conventions for the full statement.

Top-level layout

src/
├── main.ts, polyfills.ts, test.ts, index.html
├── environments/          generated + committed environment files
├── styles/                global SCSS (8 entry points)
├── assets/                images, fonts, SCSS include path
└── app/
    ├── app.module.ts              composition root
    ├── app-routes.module.ts       route aggregation
    ├── app.component.ts/.html     bootstrap component
    ├── config.ts                  AppConfigService + ThemeConfig
    ├── store/app.reducers.ts      AppState + reducer map
    ├── store-debugger.ts          meta-reducer
    ├── guards/                    app-level guards
    ├── mocks/                     test-only doubles and pipes
    ├── pyb-material/              Angular Material re-export module
    ├── shared/                    application-wide library (~67 components)
    ├── auth/                      login, logout, session state
    ├── app-welcome/               landing page
    ├── admin/                     DEV-only tooling
    ├── suppliers/                 the core domain (~200 components)
    ├── processes/                 payment batches
    ├── marketplaces/              marketplace + gateway catalogue
    ├── underwriting/              cross-supplier UW tracker
    ├── reports/                   internal + external reporting
    ├── crm-tools/                 notes, tasks, files, emails, events
    ├── emails/                    email routes (components live in crm-tools)
    └── manage/                    back-office configuration (~79 components)

Module reference

app (root)

Not a feature module but the composition root. AppModule declares only AppComponent and MainLayoutComponent, imports every feature module eagerly, registers the reducer map and effects, and provides ~25 application-level providers including the DI substitutions for abstract services. Detailed in bootstrap and composition root.

auth

Login and session. Contains login/, logout/, google-auth-login/, guards/auth.guard.ts, auth-interceptor.ts and the store/ slice (auth.actions.ts, auth.reducers.ts, auth.effects.ts). It owns the only route table declared with RouterModule.forChild outside the aggregate (auth-routing.module.ts: /login, /logout).

app-welcome

The post-login landing page (/welcome, /welcome/:messageCode). The message code renders a canned message from MessageService — used for "install the extension", "cannot receive supplier token" and test-environment login constraints.

admin

DEV-permission-only tooling: feature-flags/ (runtime flag switching, including for EVA) and qa/. Routed under /admin with a redirect to /admin/feature-flags. See DEV Admin.

suppliers

By far the largest module (~200 components) and the heart of the application.

suppliers/
├── enums/                     routing-number validation statuses, uw-status, …
├── model/                     ~35 models: supplier, marketplace link, funding,
│                              payment config, balance, cards, compliance, …
├── services/                  ~35 services: supplier, payment config, deposit
│                              account, cards, CLI, EFS, loans, compliance,
│                              email preferences, referral, winback, workflow, …
├── store/
│   ├── supplier/              the supplier slice (actions/reducers/effects)
│   └── background-reports/     background report slice
├── supplier-list/             the search/browse grid
├── supplier/                  the per-supplier workspace, one folder per tab
│                              and one per modal action
├── utils/, mock-data/
└── suppliers.module.ts

The supplier/ subtree is itself a map of the domain — supplier-general, supplier-onboarding, supplier-underwriting, supplier-advances, supplier-payment, supplier-fees, supplier-marketplaces, supplier-marketplace-statements, supplier-reports, supplier-health, supplier-receivables, supplier-transaction-summary, supplier-transaction-details, supplier-contracts, supplier-efs-account, supplier-marqeta-account, supplier-awx-account (whose awx-disputes/ child owns the Airwallex disputes page), supplier-amazon-lending, supplier-summary, supplier-2fa, plus ~20 action/dialog folders (add-receivable, add-chargeback, add-writeoff, cancel-supplier, suspend-supplier, delete-supplier-account, load-earnings, load-remittance, …).

processes

Fund-transfer batches: process-list, process-add, process-edit, process-batches, supplier-payments-details, pending-edit, and balance-approval (which is routed under both /processes/approval and /proceses/approval). Services wrap the internal API’s paymentBatches and pending_review endpoints.

marketplaces

The marketplace catalogue (marketplace-list, marketplace) with model/, service/ (including gateway.service.ts) and a small store/ slice. Routed under /marketplaces.

underwriting

A single component — tracker/ — behind the UNDERWRITING_TRACKER flag. The per-supplier underwriting UI lives in suppliers/supplier/supplier-underwriting, not here.

reports

report-list, report-add, report-edit, report-table, external-report-list, waiting-suppliers, with model/, dto/, pipes/, service/ and a mock/ folder of JSON fixtures. Internal reports are configuration-driven views over database objects.

See reports.

crm-tools

The activity timeline and task system: actions-add, actions-add-fabs, actions-list, actions-list-pinned, notes, tasks, files, emails, comments, events, crm-sidebar, plus models/, services/, shared/ and the store/ slice. Routes /tasks/list/:filterId/filter.

See CRM.

emails

Routes only (emails-routing.routes.ts). /emails/list and /emails/list/:filterId/filter render EmailListComponent and EmailPreviewComponent from crm-tools/emails. There are no components in this folder — a deliberate thin routing shim.

See emails.

manage

Back-office configuration (~79 components):

Folder Purpose

batch-imports/

Bulk CSV actions (deposit accounts, pre-funded cards, bulk notes) plus the CLI action runner.

event-rules/

Event-rule v1: list, add/edit with selector and action sub-forms (create-task, send-email, edit-supplier, send-to-event-bridge), and history.

event-rules-2/

The v2 (beta) rule editor.

events/

The raw event stream with badge and filter components.

users/, perm-groups/

Internal user and permission-group administration.

global-settings/, configs/

Key/value configuration, with its own store slice and selectors.

email-settings/

Outbound email configuration.

fee-settings/

Default fee configuration (list/add/edit).

onboarding/

Onboarding templates and their marketplace assignments.

contracts/

Contract templates and defaults.

month-end-close/

The accounting close screen.

permission-error-pop-up/

Shared "access denied" dialog.

store/

The onboarding slice.

See manage.

shared

The application-wide library — ~67 components plus directives, pipes, services, interceptors, guards, resolvers and models. Grouped by concern:

Area Contents

Layout

layout/ (MainLayoutComponent, app-stage-info, fab-holder-nav, layout store slice), sidenav/, footer/, page-not-found/.

Tables

data-table/, data-table-grid/, data-table-ag-grid/, pyb-ag-grid/, data-grid/, simple-table/, cell-components/, pyb-pagination/. Four generations — see table generations.

Dialogs

dialog/ (module + service), confirm-dialog/, confirm-delete/, information-dialog/, reason-dialog/, summary-dialog/.

Forms

forms/ (dynamic form controls), card-formgroup/, inline-edit/, input-file/, radiobuttons/, checkbox-filters/, time-select-picker/, editor/ (TinyMCE), chip/, text-value/, drag-and-drop-list/.

Filtering

filters/, filtering-panel/, search-overlay/ (+ the 3.0 search engine service and Elastic highlight handling).

Documents

apps-document/, b2b-document/, pyb-documents/ — three document backends.

Platform

interceptors/, cache/, feature-flags/, users/, resolvers/, guards (in auth/ and the root guards/), error-handling/, services/ (error logger/parser/visualisation, cookies, long-term contracts, toastr mock), eva/, iframe/, sse.service.ts, monitor.service.ts, version.service.ts, vpn-tester.service.ts, message.service.ts, table-events.service.ts, logger.ts, dynamic-embedder.service.ts.

Utilities

utils/ (incl. the utils store slice and route-access-resolver.ts), functions/, enums/, consts/, interfaces/, models/, animations/, csv-export-service/, lookup-service/, component-subscriber/ (SubscriberComponent base class for subscription cleanup), http-loader/, loading-spinner/, spinner-button/, no-data/, task-count-badge/, title-with-icon/, onboarding/, external-report/, reset-password/, actions-menu/, actions-add-fabs/.

pyb-material

A single module that imports and re-exports the ~29 Angular Material modules the app uses. Its purpose is stated in the repository README: consistent imports, "important especially in unit tests".

mocks

Test-only module with shared doubles and pipes/. Not for production paths.

guards (root)

FeatureFlagsGeneralGuard — initialises feature flags once the user is known, and in non-production logs the resolved flag table to the console. SubPermissionsGuard — checks requireOneOfSubPermissions from route data and toasts "Access denied." on failure.

Where to put new code

You are adding… Put it…

A new supplier tab

suppliers/supplier/<tab-name>/, with a route child under :supplierKey in suppliers/suppliers-routing.routes.ts, guarded with the appropriate RESTRICTED_*_CONFIG spread.

A new back-office screen

manage/<screen>/, route child under /manage.

A service used by one module

<module>/services/ (or <module>/service/ — both spellings exist; match the module you are in).

A service used app-wide

shared/services/<concern>/, and provide it in AppModule if it must be a singleton.

A model/DTO

<module>/model/<concept>.model.ts — one concept per file.

A reusable presentational component

shared/<component>/, declared and exported by SharedModule.

A new store slice

<module>/store/, then register the reducer in src/app/store/app.reducers.ts and any effects class in EffectsModule.forRoot([…​]) in app.module.ts. Only do this if more than one screen needs the state.