# thegondrol/nilam-ocr-npwp architecture

> Architecture diagram of the GitHub repository thegondrol/nilam-ocr-npwp, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/thegondrol/nilam-ocr-npwp
- Repository: https://github.com/thegondrol/nilam-ocr-npwp

## Overview

This repository implements a five-service Indonesian NPWP OCR product. A client submits a document to the orchestrator, which validates it, asks guardrails for a verdict, and starts OCR for accepted documents. The asynchronous stages then perform OCR, structure extracted text into NPWP fields, and score field confidence; the orchestrator polls stage status and returns the outcome. The shared library supplies web conventions and the background pipeline, persistence, callbacks, and handoffs. README and sampled entry points support these relationships; several service internals were not sampled, so uncertain implementation-level links are omitted.

Main entry points: [`libs/ocr_common/ocr_common/web/app.py`](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/web/app.py) (Web service toolkit), [`libs/ocr_common/ocr_common/pipeline/stage.py`](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/stage.py) (Stage pipeline), [`services/orchestrator/app/services/extract_service.py`](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/services/extract_service.py) (Extract service), [`services/ekstraksi/app/services/ekstraksi_service.py`](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/services/ekstraksi_service.py) (OCR service)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Request orchestration"]
  node_orchestrator_api["Extract API<br/>[extract_ocr.py]"]
  node_extract_service["Extract service<br/>[extract_service.py]"]
  node_guardrails_client["Guardrails client<br/>[guardrails.py]"]
  node_ocr_client["Ekstraksi client<br/>[ekstraksi.py]"]
  node_status_clients["Stage status clients<br/>[stages.py]"]
  node_waiter["Pipeline waiter<br/>[pipeline_waiter.py]"]
end

subgraph group_checks["Document validation"]
  node_guardrails_api["Guardrails API<br/>[guardrails.py]"]
  node_guardrails_service["Page and document verdict"]
  node_page_model["Page classifier<br/>[efficientnet.py]"]
end

subgraph group_stages["OCR stages"]
  node_ocr_jobs["OCR job API<br/>[jobs.py]"]
  node_ocr_service["OCR service"]
  node_ocr_engine["OCR engine<br/>[paddle.py]"]
  node_structuring_jobs["Structuring job API<br/>[jobs.py]"]
  node_structuring_service["Structuring service"]
  node_structuring_rules["NPWP rules<br/>[npwp_rules.py]"]
  node_scoring_jobs["Scoring job API<br/>[jobs.py]"]
  node_scoring_service["Scoring service<br/>[scoring_service.py]"]
  node_trust_model["Trust model<br/>[trust_model.py]"]
end

subgraph group_shared["Shared runtime"]
  node_pipeline["Stage pipeline<br/>[stage.py]"]
  node_callback_outbox["Callbacks and outbox<br/>[callbacks.py]"]
  node_web_common["Web service toolkit<br/>[app.py]"]
end

subgraph group_state["Pipeline state"]
  node_job_store[("Job and result store<br/>[repository_sql.py]")]
end

node_caller(("API caller"))
node_central_orchestration(("Central orchestrator"))

node_caller -->|"submits document"| node_orchestrator_api
node_orchestrator_api -->|"handles request"| node_extract_service
node_extract_service -->|"requests verdict"| node_guardrails_client
node_guardrails_client -->|"checks document"| node_guardrails_api
node_guardrails_api -->|"runs check"| node_guardrails_service
node_guardrails_service -->|"classifies pages"| node_page_model
node_extract_service -->|"starts accepted job"| node_ocr_client
node_ocr_client -->|"submits OCR job"| node_ocr_jobs
node_extract_service -->|"waits for stages"| node_waiter
node_waiter -->|"polls status"| node_status_clients
node_ocr_jobs -->|"dispatches job"| node_ocr_service
node_ocr_service -->|"recognizes text"| node_ocr_engine
node_ocr_service -->|"runs background stage"| node_pipeline
node_pipeline -->|"stores stage state"| node_job_store
node_pipeline -->|"dispatches updates"| node_callback_outbox
node_ocr_service -->|"hands off OCR result"| node_structuring_jobs
node_structuring_jobs -->|"dispatches job"| node_structuring_service
node_structuring_service -->|"structures fields"| node_structuring_rules
node_structuring_service -->|"runs background stage"| node_pipeline
node_structuring_service -->|"hands off fields"| node_scoring_jobs
node_scoring_jobs -->|"dispatches job"| node_scoring_service
node_scoring_service -->|"scores confidence"| node_trust_model
node_scoring_service -->|"runs background stage"| node_pipeline
node_callback_outbox -->|"sends stage callback"| node_central_orchestration
node_central_orchestration -.->|"calls entry point"| node_orchestrator_api
node_web_common -->|"provides web runtime"| node_orchestrator_api
node_web_common -->|"provides web runtime"| node_guardrails_api
node_web_common -->|"provides web runtime"| node_ocr_jobs
node_web_common -->|"provides web runtime"| node_structuring_jobs
node_web_common -->|"provides web runtime"| node_scoring_jobs

click node_orchestrator_api "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/api/extract_ocr.py"
click node_extract_service "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/services/extract_service.py"
click node_guardrails_client "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/clients/guardrails.py"
click node_ocr_client "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/clients/ekstraksi.py"
click node_status_clients "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/clients/stages.py"
click node_waiter "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/services/pipeline_waiter.py"
click node_guardrails_api "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/guardrails/app/api/guardrails.py"
click node_guardrails_service "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/guardrails/app/services/guardrails_service.py"
click node_page_model "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/guardrails/app/ml/efficientnet.py"
click node_ocr_jobs "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/api/jobs.py"
click node_ocr_service "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/services/ekstraksi_service.py"
click node_ocr_engine "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/ml/paddle.py"
click node_structuring_jobs "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/structuring/app/api/jobs.py"
click node_structuring_service "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/structuring/app/services/structuring_service.py"
click node_structuring_rules "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/structuring/app/ml/npwp_rules.py"
click node_scoring_jobs "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/scoring/app/api/jobs.py"
click node_scoring_service "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/scoring/app/services/scoring_service.py"
click node_trust_model "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/scoring/app/ml/trust_model.py"
click node_pipeline "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/stage.py"
click node_callback_outbox "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/callbacks.py"
click node_web_common "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/web/app.py"
click node_job_store "https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/repository_sql.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_orchestrator_api,node_extract_service,node_guardrails_client,node_ocr_client,node_status_clients,node_waiter toneBlue
class node_guardrails_api,node_guardrails_service,node_page_model toneAmber
class node_ocr_jobs,node_ocr_service,node_ocr_engine,node_structuring_jobs,node_structuring_service,node_structuring_rules,node_scoring_jobs,node_scoring_service,node_trust_model,node_caller toneMint
class node_pipeline,node_callback_outbox,node_web_common toneRose
class node_job_store,node_central_orchestration toneIndigo
```

## Components

### Request orchestration

- [Extract API](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/api/extract_ocr.py): `services/orchestrator/app/api/extract_ocr.py`
- [Extract service](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/services/extract_service.py): `services/orchestrator/app/services/extract_service.py`
- [Guardrails client](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/clients/guardrails.py): `services/orchestrator/app/clients/guardrails.py`
- [Ekstraksi client](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/clients/ekstraksi.py): `services/orchestrator/app/clients/ekstraksi.py`
- [Stage status clients](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/clients/stages.py): `services/orchestrator/app/clients/stages.py`
- [Pipeline waiter](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/orchestrator/app/services/pipeline_waiter.py): `services/orchestrator/app/services/pipeline_waiter.py`

### Document validation

- [Guardrails API](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/guardrails/app/api/guardrails.py): `services/guardrails/app/api/guardrails.py`
- [Page and document verdict](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/guardrails/app/services/guardrails_service.py): `services/guardrails/app/services/guardrails_service.py`
- [Page classifier](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/guardrails/app/ml/efficientnet.py): `services/guardrails/app/ml/efficientnet.py`

### OCR stages

- [OCR job API](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/api/jobs.py): `services/ekstraksi/app/api/jobs.py`
- [OCR service](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/services/ekstraksi_service.py): `services/ekstraksi/app/services/ekstraksi_service.py`
- [OCR engine](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/ekstraksi/app/ml/paddle.py): `services/ekstraksi/app/ml/paddle.py`
- [Structuring job API](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/structuring/app/api/jobs.py): `services/structuring/app/api/jobs.py`
- [Structuring service](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/structuring/app/services/structuring_service.py): `services/structuring/app/services/structuring_service.py`
- [NPWP rules](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/structuring/app/ml/npwp_rules.py): `services/structuring/app/ml/npwp_rules.py`
- [Scoring job API](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/scoring/app/api/jobs.py): `services/scoring/app/api/jobs.py`
- [Scoring service](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/scoring/app/services/scoring_service.py): `services/scoring/app/services/scoring_service.py`
- [Trust model](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/services/scoring/app/ml/trust_model.py): `services/scoring/app/ml/trust_model.py`

### Shared runtime

- [Stage pipeline](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/stage.py): `libs/ocr_common/ocr_common/pipeline/stage.py`
- [Callbacks and outbox](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/callbacks.py): `libs/ocr_common/ocr_common/pipeline/callbacks.py`
- [Web service toolkit](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/web/app.py): `libs/ocr_common/ocr_common/web/app.py`

### Pipeline state

- [Job and result store](https://github.com/thegondrol/nilam-ocr-npwp/blob/main/libs/ocr_common/ocr_common/pipeline/repository_sql.py): `libs/ocr_common/ocr_common/pipeline/repository_sql.py`

### Other components

- **API caller**
- **Central orchestrator**

## Connections

- API caller → Extract API: submits document
- Extract API → Extract service: handles request
- Extract service → Guardrails client: requests verdict
- Guardrails client → Guardrails API: checks document
- Guardrails API → Page and document verdict: runs check
- Page and document verdict → Page classifier: classifies pages
- Extract service → Ekstraksi client: starts accepted job
- Ekstraksi client → OCR job API: submits OCR job
- Extract service → Pipeline waiter: waits for stages
- Pipeline waiter → Stage status clients: polls status
- OCR job API → OCR service: dispatches job
- OCR service → OCR engine: recognizes text
- OCR service → Stage pipeline: runs background stage
- Stage pipeline → Job and result store: stores stage state
- Stage pipeline → Callbacks and outbox: dispatches updates
- OCR service → Structuring job API: hands off OCR result
- Structuring job API → Structuring service: dispatches job
- Structuring service → NPWP rules: structures fields
- Structuring service → Stage pipeline: runs background stage
- Structuring service → Scoring job API: hands off fields
- Scoring job API → Scoring service: dispatches job
- Scoring service → Trust model: scores confidence
- Scoring service → Stage pipeline: runs background stage
- Callbacks and outbox → Central orchestrator: sends stage callback
- Central orchestrator → Extract API: calls entry point
- Web service toolkit → Extract API: provides web runtime
- Web service toolkit → Guardrails API: provides web runtime
- Web service toolkit → OCR job API: provides web runtime
- Web service toolkit → Structuring job API: provides web runtime
- Web service toolkit → Scoring job API: provides web runtime
