# Local / Gyomu

## Overview

The `local.gyomu` package is the HTTP API gateway for the **eo customer base system** (eo顧客基幹システム). It provides the integration layer that bridges external clients — web frontends, LINE, operator support consoles, and sales channels — with the backend EJB business service infrastructure.

The package is responsible for exposing REST endpoints as JAX-RS `@POST` resource classes (60+ endpoints in total, each handling one external interface / 外部I/F), with the abstract base class [`ApiServerLocalBase`](source/koptWebRest/src/local/gyomu/ApiServerLocalBase.java) providing shared logic for authentication, error handling, and business service invocation. The Japanese file header describes this as "業務AP システム個別共通クラスです" — a common class for individual business application systems.

The module covers a wide range of domains:

- **Customer information management** — address updates, basic info lookup, contact info, prospect CRUD, data utilization consent, SYSID uniqueness
- **LINE integration** — usage info, contract info, member rank, billing, referral codes — all with header-based system ID routing
- **Billing and contract** — billing lookups, discount amounts, price correspondence, contract transfers, discount proposals
- **Web application intake** (WEB 申請) — application content lists, OTP issuance, display availability, eoID binding, building info search, MNP checks
- **Authentication and security** — one-time key sending, OTP authentication, account auth
- **Sales / operator support** — inquiry history, response history, handling code reflection, malware blocking, campaign applicability, ID aggregated info
- **Promotional services** — Netflix subscriptions, gift code issuance, prize codes, SMS notifications, discount info
- **Installation and construction** — construction case info, STB course reservations, equipment provisioning, progress status
- **Credit and payment** — credit pre-approval, credit payment authorization (with runtime-determined system IDs)
- **Address and location** — address kana lookup, address master dropdowns
- **Fee calculation** — contract info, discount info, building penalty info for billing computation

## Sub-module Guide

The module does not have child wiki pages under `local.gyomu.api`. Instead, the 60+ endpoint classes work together as a **single integration layer**. They do not depend on each other but converge on two shared foundations:

1. **[`ApiServerLocalBase`](source/koptWebRest/src/local/gyomu/ApiServerLocalBase.java)** — the abstract base class that every endpoint extends. It provides the template method pattern (`execute` → `run` → `logicExecute`), shared service invocation methods (`callBpService`, `callBpService2`, `callBpServiceForLine`), and consistent error handling.

2. **[`local.gyomu.api.common`](source/koptWebRest/src/local/gyomu/api/common/ApiBpInterface.java)** — helper classes including `ApiBpInterface` (error info keys, service invocation constants) and `ApiCommonItem` (operational metadata like job ID and operator ID).

The endpoint classes can be understood through the business domains they serve rather than as independent modules. Each domain group shares:

- A common set of upstream business services (e.g., CMP, ESS, OPS systems)
- A consistent code naming convention (prefixes like `CK*` for customer, `FUI*` for web frontend, `KK*` for contracts, `AC*` for usage)
- A shared invocation pattern, with LINE-specific classes using `callBpServiceForLine()` and header-based system ID routing

### Domain interaction model

```mermaid
flowchart TD
    subgraph CLIENT["Client Tier"]
        WEB["Web Frontend"]
        LINE["LINE Platform"]
        OPS["Operator Support"]
    end

    subgraph API_LAYER["API Gateway Layer<br/>local.gyomu.api"]
        END1["60+ Endpoint Classes<br/>JAX-RS @POST"]
    end

    subgraph BASE["Common Base Class<br/>ApiServerLocalBase"]
        AUTH["Authentication<br/>Validation"]
        ROUTE["System ID<br/>Routing"]
        SERVCALL["callBpService<br/>callBpService2<br/>callBpServiceForLine"]
    end

    subgraph BP_LAYER["Business Service Layer<br/>eo.ejb.cbs.mainproc"]
        CMP["CMP - Customer Mgmt"]
        ESS["ESS - Sales Channel"]
        OPS_BP["OPS - Operator Support"]
        LINE_BP["LINE Platform"]
        OTHER["Other Systems<br/>FRN, FTR, DEN"]
    end

    WEB --> END1
    LINE --> END1
    OPS --> END1
    END1 --> AUTH
    END1 --> ROUTE
    ROUTE --> SERVCALL
    AUTH --> SERVCALL
    SERVCALL --> CMP
    SERVCALL --> ESS
    SERVCALL --> OPS_BP
    SERVCALL --> LINE_BP
    SERVCALL --> OTHER
```

## Key Patterns and Architecture

### Template method flow

Every endpoint follows a uniform three-phase pattern, making the package highly regular and predictable:

```mermaid
sequenceDiagram
    autonumber
    participant C as Client
    participant EP as API Endpoint
    participant BASE as ApiServerLocalBase
    participant BP as Business Service
    participant R as HTTP Response

    C->>EP: POST execute(request)
    EP->>BASE: exec(APIID, request, context)
    BASE->>BASE: Authentication, validation
    BASE->>EP: run(partsBean)
    EP->>EP: logicExecute(partsBean)
    EP->>BP: callBpService(serviceId, partsBean)
    BP-->>EP: outputMap(result)
    EP->>EP: Extract result from outMap
    EP-->>BASE: ApiServerPartsBean(response)
    BASE-->>EP: Response
    EP-->>R: HTTP Response
```

1. **`execute()`** — Public JAX-RS entry point annotated with `@POST`. Extracts the request and servlet context, then delegates to the base class's `exec()` for common processing.
2. **`run()`** — Template method called by the base class after common processing. The override calls `logicExecute()`.
3. **`logicExecute()`** — Private method containing the domain-specific logic. Calls business service methods, extracts results, returns a populated `ApiServerPartsBean`.

### Business service invocation variants

The base class provides several methods for calling the EJB business layer:

| Method | When used | Purpose |
|---|---|---|
| `callBpService()` | Most classes | Standard synchronous call to an EJB business service |
| `callBpService2()` | Classes needing runtime system ID (e.g., `CRIFE055`, `KKIFE489`) | Accepts a runtime system identifier instead of a compile-time constant |
| `callBpServiceForLine()` | LINE-specific classes (`ACIFE070`, `KKIFE411`, `KKIFE412`) | LINE-integrated services; response body nested under `BODY_INFO` key |
| `callBpService(serviceId1, serviceId2, ...)` | Multi-service operations | Chains two sequential business service calls; second call feeds output of first |

### Error handling convention

The base class distinguishes two exception types:

- **`ApiServerExceptionGyomuErr`** — Business error (expected, controllable). The return code from the BP service is checked against a whitelist. When matched, the error code and message are placed in `reqPartsBean.setErrList()` and the exception is re-thrown.
- **`ApiServerExceptionGyomuSysErr`** — System error (unexpected). Wrapped from generic `Exception` in the base class's `mainExec()` catch block.

Most classes return results directly. A subset (including [`FUIFE168`](source/koptWebRest/src/local/gyomu/api/FUIFE168.java), [`FUIFE194`](source/koptWebRest/src/local/gyomu/api/FUIFE194.java), [`FUIFE202`](source/koptWebRest/src/local/gyomu/api/FUIFE202.java), [`KKIFE475`](source/koptWebRest/src/local/gyomu/api/KKIFE475.java), [`KKIFE445`](source/koptWebRest/src/local/gyomu/api/KKIFE445.java)) extracts `ApiBpInterface.ERROR_INFO` from the service result for structured error propagation.

[`FUIFE194`](source/koptWebRest/src/local/gyomu/api/FUIFE194.java) is the most complex handler — it wraps service calls in nested `try/catch` blocks distinguishing business errors from system errors, injects an `errCode` of `"3001"` when the error list is empty, and for `func_code == "3"` additionally sends a completion notification and deletes stored web application data.

### System ID routing

Each endpoint class defines a compile-time `SYSTEM_ID` constant (e.g., `"CMP1"`, `"ESS1"`, `"OPS1"`, `"FRN1"`) indicating which upstream system the business service belongs to. LINE-integrated classes (modified under ticket **ANK-3355-08-00**) read the system ID from the HTTP `Sysid` header at runtime, allowing a single API gateway to serve multiple LINE environments. Credit-related endpoints (`KKIFE489`, `KKIFE490`) extract the system ID from the request body field `system_id` for dynamic provider routing.

### Data model

The package uses the generic [`ApiServerPartsBean`](source/koptWebRest/src/local/gyomu/api/ACIFE070.java) envelope for all requests and responses. This carries a `Header` map (routing metadata), a `Body` map (domain payload), and an `ErrList` (structured errors). The response from a business service is a `Map<String, Object>` keyed by `serviceId + "01CC"`, with business data and error information stored under standard keys (`BODY_INFO`, `ERROR_INFO`).

```mermaid
flowchart TD
    subgraph REQ["Request Envelope<br/>ApiServerPartsBean"]
        Header["Header Map<br/>sysid, uketsukesya"]
        Body["Body Map<br/>Domain keys"]
        ErrList["ErrList List"]
    end

    subgraph RESP["BP Result Map"]
        Key["serviceId + 01CC"]
        ErrInfo["ERROR_INFO"]
        BodyInfo["BODY_INFO<br/>LINE services"]
    end

    Header --> REQ
    Body --> REQ
    ErrList --> REQ
    Key --> RESP
    ErrInfo --> Key
    BodyInfo --> Key
```

## Dependencies and Integration

### Source file

| Source file | Role |
|---|---|
| [`ApiServerLocalBase.java`](source/koptWebRest/src/local/gyomu/ApiServerLocalBase.java) | Abstract base class; template method, service invocation, error handling |

### Package dependencies

| Dependency | Description |
|---|---|
| `eo.ejb.cbs.mainproc` | EJB call-by-service infrastructure |
| `com.fujitsu.futurity.bp.custom.bpm.chsv0066` | Fujitsu BPM service for customer operations |
| `com.fujitsu.futurity.bp.custom.bpm.chsv0065` | Fujitsu BPM service |
| `com.fujitsu.futurity.bp.custom.common` | Fujitsu runtime common libraries |
| `eo.business.common` | Shared business utilities |
| `com.fujitsu.futurity.bp.custom.bpm.chsv0067` | Fujitsu BPM service |
| `local.gyomu.api.common` | Common API helpers (`ApiBpInterface`, `ApiCommonItem`) |
| `eo.business.service` | Business service interfaces |

### Upstream systems

Each endpoint class maps to one or more upstream systems via its `SYSTEM_ID`:

- `CMP1` — Core customer management platform (largest consumer, covers customer data, billing, promotions)
- `ESS1` — ESS (sales channel) system
- `OPS1` — Operator support system
- `FRN1` — FRN (notification) system
- `API1` — LINE integration platform
- `FTR1` — Web frontend integration
- Runtime `system_id` — Dynamic routing (credit/payment services)

### External dependencies

- **JAX-RS** (`javax.ws.rs`) — REST endpoint annotation (`@POST`, `@Path`)
- **Servlet API** (`javax.servlet`) — HTTP request/response context injection
- **`com.k_opti.api_parts.server`** — API parts framework (envelope bean, exception types)

## Notes for Developers

### Adding a new endpoint

1. Create a new class extending `ApiServerLocalBase` in this package.
2. Define the constants: `APIID` (class name), `SERVICE_ID` (business service name), `SYSTEM_ID` (upstream system), and `JOB_ID` (operation trace ID).
3. Override `execute()` to call `super.exec(APIID, pRequest, pContext)`.
4. Override `run()` to call `this.logicExecute(reqPartsBean)`.
5. Implement `logicExecute()`:
   - Call the appropriate `callBpService*()` method.
   - Extract the result using `outMap.get(serviceId + _01CC)`.
   - If the business service may return errors, check for `ApiBpInterface.ERROR_INFO` and handle as needed.
   - Create and return a new `ApiServerPartsBean` with the result body.

### LINE integration caveat

Classes modified under **ANK-3355-08-00** read the system ID from the `Sysid` HTTP header rather than the request body. This was done because multiple services are called in sequence through the LINE platform, and the system ID needs to be globally determined rather than per-request-body. If adding a new LINE-integrated endpoint, follow this pattern — declare a `private String HTTP_HEADER_SYSID = ""` field and read it in `execute()`.

### Naming convention

The class name encodes the interface ID. The prefix indicates the domain:

| Prefix | Domain | Examples |
|---|---|---|
| `AC*` | Usage/charge information | `ACIFE070` |
| `CC*` | Authentication/security | `CCIFE005`, `CCIFE006` |
| `CH*` | Billing/charge | `CHIFE067`, `CHIFE528` |
| `CK*` | Customer management | `CKIFE051`, `CKIFE053` |
| `CR*` | Response/inquiry records | `CRIFE054`, `CRIFE055` |
| `FUI*` | Web/frontend user intake | `FUIFE168`, `FUIFE194` |
| `KK*` | Contract/kyakuyaku information | `KKIFE403`, `KKIFE445` |
| `KUI*` | Construction/unique operations | `KUIFE079`, `KUIFE081` |
| `ZM*` | Address/master data | `ZMIFE059`, `ZMIFE060` |

### Testing guidance

Each class is thin (typically 100-200 lines) and mostly delegates to the base class and the bp service layer. Unit testing should focus on:

- Correct service ID and system ID assignment
- Proper error extraction and re-throwing in classes that handle errors
- LINE-specific system ID header extraction
- Response body unwrapping (especially `BODY_INFO` extraction for LINE services)

### File size note

Some source files (e.g., [`KKIFE475`](source/koptWebRest/src/local/gyomu/api/KKIFE475.java)) exceed typical sizes and contain custom logic beyond the standard delegation pattern — such as stripping prefix underscores from field names for SOAP naming compliance. Always check for non-standard logic in `logicExecute()` before applying bulk refactoring.
