feat: archive zoo_backup for home sync
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
# Paisy — Development Guidelines
|
||||
|
||||
## Code Quality Standards
|
||||
|
||||
### Logging
|
||||
- Use `@Log4j2` (Lombok) for existing modules that already use Log4j2 (e.g., `AbstractMeldung`)
|
||||
- Use `@Slf4j` (Lombok) for new code — this is the preferred default
|
||||
- Use parameterized logging: `log.debug("Value: {}", value)` — never string concatenation
|
||||
- Some legacy code mixes styles: `log.debug("text " + var)` — refactor to parameterized when touching these lines
|
||||
- Log levels: `debug` for flow tracing, `warn` for recoverable issues, `error` for failures
|
||||
|
||||
### Naming Conventions
|
||||
- Package: `com.adp.de.paisy.modules.<module>` for modules, `com.adp.de.<module>` for legacy
|
||||
- German domain terms preserved in class/field names: `Fehlzeiten`, `Lohnkonto`, `Vorlaufsatz`, `Nachlaufsatz`, `Meldekorrekturen`
|
||||
- JAXB-generated classes use German XML element names as Java identifiers: `getAngabenZurPersonAV()`, `getBeschreibungTaetigkeitDE()`
|
||||
- Constants use UPPER_SNAKE_CASE: `EMPTY_DATE_LONG`, `EMPTY_BBNR`, `MAX_DBFZ`
|
||||
- Date formatters as `final` fields: `bausteinf`, `pai022f`, `PAI_SHORT`
|
||||
|
||||
### Field Visibility
|
||||
- `protected` for fields shared with subclasses (common in abstract controllers)
|
||||
- `private` with Lombok `@Getter`/`@Setter` for DTOs
|
||||
- `static private final` for constants (PDDI layer uses tab-indented style)
|
||||
|
||||
## Structural Conventions
|
||||
|
||||
### Module Entry Point Pattern
|
||||
```java
|
||||
@Slf4j
|
||||
@Service("module-name")
|
||||
@Lazy
|
||||
public class ModuleRunner implements ConsoleService {
|
||||
@Override
|
||||
public void run(String... args) throws Exception { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
### Abstract Controller Pattern (5/5 files)
|
||||
Business modules use abstract base classes for shared logic:
|
||||
```java
|
||||
@Log4j2
|
||||
public abstract class AbstractMeldung {
|
||||
// Shared date formatters, parsers, PAISY interaction
|
||||
protected Person person;
|
||||
protected Fehlzeiten fz;
|
||||
|
||||
public Person initBaustein(Datenbaustein main, DBNA dbna, ...) { /* ... */ }
|
||||
protected Lohnkonto parseLohnkonto(...) { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
### Datenbaustein (Data Block) Pattern (5/5 files)
|
||||
Core data exchange pattern — field-based data blocks with positional access:
|
||||
```java
|
||||
Datenbaustein main = ...;
|
||||
main.setValue("FEKZ", "0");
|
||||
main.setValue("VSNR", person.getValue("VSNR"));
|
||||
String value = d508b.getValue("F39-AVUWFWZ-10-50-8B");
|
||||
```
|
||||
|
||||
### ServiceCenter Singleton Pattern
|
||||
Central access point for PAISY system interaction:
|
||||
```java
|
||||
ServiceCenter.INSTANCE().getBaustein(Datengruppe.NAME, vorgangsID);
|
||||
ServiceCenter.INSTANCE().getPaisy().pgmFunktionCall("S;" + bbnrvu + ";");
|
||||
ServiceCenter.INSTANCE().getPaisy().pgmReadLine();
|
||||
```
|
||||
|
||||
### EMFactory Singleton Pattern
|
||||
Each module has its own EntityManager factory:
|
||||
```java
|
||||
EMFactoryEAU emFactory = EMFactoryEAU.getInstance();
|
||||
FlywayController flyway = new FlywayController(emFactory);
|
||||
flyway.migrate("EAU", "2024_09_08_17_48_11");
|
||||
```
|
||||
|
||||
## JAXB XML Binding Pattern (3/5 files)
|
||||
|
||||
JAXB-generated classes follow a strict pattern for GKV data exchange:
|
||||
|
||||
```java
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@XmlType(name = "", propOrder = { "steuerungsdaten", "angabenZurPersonAV", ... })
|
||||
@XmlRootElement(name = "A1_Ausnahmevereinbarung",
|
||||
namespace = "http://www.gkv-datenaustausch.de/XMLSchema/A1_Ausnahme/2.0")
|
||||
public class A1Ausnahmevereinbarung {
|
||||
|
||||
@XmlElement(name = "Steuerungsdaten",
|
||||
namespace = "http://www.gkv-datenaustausch.de/XMLSchema/A1_Ausnahme/2.0",
|
||||
required = true)
|
||||
protected SteuerungsdatenAGV2Ctp steuerungsdaten;
|
||||
}
|
||||
```
|
||||
|
||||
Key rules:
|
||||
- Nested `public static class` for complex type hierarchies
|
||||
- German Javadoc: `"Ruft den Wert der X-Eigenschaft ab"` / `"Legt den Wert der X-Eigenschaft fest"`
|
||||
- `jakarta.xml.bind.annotation.*` (Jakarta EE, not javax)
|
||||
- `XMLGregorianCalendar` for date fields, `BigInteger` for numeric codes
|
||||
- `KennzeichenAlphanumerischTyp` enum for J/N flag fields
|
||||
|
||||
## PDF Generation Pattern (2/5 files)
|
||||
|
||||
Using OpenPDF (iText fork) for government-compliant PDF reports:
|
||||
|
||||
```java
|
||||
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
|
||||
PdfWriter writer = PdfWriter.getInstance(document, baos);
|
||||
document.open();
|
||||
|
||||
// Header
|
||||
Paragraph headline = new Paragraph("EuBP", getHeaderFont());
|
||||
document.add(headline);
|
||||
|
||||
// Two-column table: Bezeichnung | Inhalt
|
||||
PdfPTable table = new PdfPTable(2);
|
||||
table.setWidthPercentage(75);
|
||||
table.setHorizontalAlignment(Element.ALIGN_LEFT);
|
||||
addTableHeader(table, new String[]{"Bezeichnung", "Inhalt"});
|
||||
table.addCell(createCell("Verfahrensmerkmal"));
|
||||
table.addCell(createCell(vorlaufsatz.getVerfahrensmerkmal().value));
|
||||
document.add(table);
|
||||
```
|
||||
|
||||
Font conventions:
|
||||
- Header: Helvetica Bold 18pt
|
||||
- Subheader: Helvetica Bold 14pt
|
||||
- Bold: Helvetica Bold 12pt
|
||||
- Normal: Helvetica 10pt
|
||||
- Table header background: `new Color(220, 220, 220)`
|
||||
|
||||
## ISAM/Oracle Trigger Generation (1/5 files)
|
||||
|
||||
JavaScript code generator for Oracle INSTEAD OF triggers:
|
||||
```javascript
|
||||
// gen_trigger.js — generates Oracle triggers for COBOL ISAM → Oracle mirroring
|
||||
gen("YP_ABR_STEUER", `
|
||||
,MUT_YP_ABR_STEUER.ABSCHNITT
|
||||
,MUT_YP_ABR_STEUER.BEMERKUNG
|
||||
...
|
||||
`)
|
||||
```
|
||||
Pattern: `IPW_<recname>` view → `MUT_<recname>` mutation table, with `ak_nr`/`pers_nr` lookup from `PS_YP_PERS_MAIN`.
|
||||
|
||||
## Binary Protocol Pattern (1/5 files)
|
||||
|
||||
Custom binary serialization for PDDI middleware (DocumentStream):
|
||||
- Type-tagged byte protocol: `b_null='~'`, `b_string='S'`, `b_int='i'`, `b_date='d'`
|
||||
- Compact encoding: shorts for small ints, full 8 bytes only when needed
|
||||
- Custom charset: `PaisyCharset.CHARSET` (likely ISO-8859-1)
|
||||
- Inner classes: `BytesOutput`, `Output` (stream-based), `Input` (stream-based)
|
||||
|
||||
## Date Handling Patterns
|
||||
|
||||
```java
|
||||
// German user-facing format
|
||||
DateTimeFormatter.ofPattern("dd.MM.yyyy")
|
||||
|
||||
// Internal PAISY format (8-digit)
|
||||
DateTimeFormatter.ofPattern("yyyyMMdd")
|
||||
|
||||
// Short PAISY format (6-digit, 2-digit year)
|
||||
DateTimeFormatter.ofPattern("yyMMdd")
|
||||
|
||||
// Null/empty date handling
|
||||
if (value.equals("00.00.0000")) return LocalDate.MAX;
|
||||
if (paidate.equals("0000000")) return LocalDate.MIN;
|
||||
if (paidate.equals("9999999")) return LocalDate.MAX;
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Custom exceptions: `PaisyIOException`, `PaisyRuntimeException`, `AccessDeniedException`, `PaisyNotFoundException`, `UnauthorizedException`
|
||||
- PAISY error responses start with `"F;"` — check before parsing
|
||||
- Null-safe patterns: check for null before processing sections (PDF, data blocks)
|
||||
- Reflection-based construction with explicit error messages for field count mismatches
|
||||
|
||||
## Frequently Used Annotations
|
||||
|
||||
| Annotation | Usage | Frequency |
|
||||
|-----------|-------|-----------|
|
||||
| `@Log4j2` / `@Slf4j` | Logging | Every class |
|
||||
| `@Getter` / `@Setter` | Lombok accessors | DTOs, models |
|
||||
| `@XmlElement` / `@XmlAccessorType` | JAXB binding | XML model classes |
|
||||
| `@XmlRootElement` / `@XmlType` | JAXB root types | Top-level XML types |
|
||||
| `@XmlSchemaType` | JAXB schema mapping | XML fields |
|
||||
| `@Service("name")` / `@Lazy` | Spring service registration | Module entry points |
|
||||
| `@Transactional` | DB transactions | Service methods |
|
||||
| `@Data` / `@Builder` | Lombok DTOs | Model classes |
|
||||
|
||||
## Code Idioms
|
||||
|
||||
- `CommonRoutines.paidate2Datenbaustein()` — convert PAISY date to Datenbaustein format
|
||||
- `CommonRoutines.uuid()` — generate unique dataset IDs
|
||||
- `CommonRoutines.getDocumentPath()` — get output file path
|
||||
- `ServiceCenter.INSTANCE().getPaisy().nextPaisy(line)` — iterate PAISY response lines
|
||||
- `line.split(";")` — semicolon-delimited PAISY response parsing
|
||||
- Streams with `Collectors.toCollection(ArrayList::new)` for mutable result lists
|
||||
@@ -0,0 +1,54 @@
|
||||
# Paisy — Product Overview
|
||||
|
||||
## Purpose
|
||||
|
||||
Paisy is ADP Germany's **Java monorepo** for payroll and HR government compliance. It handles all electronic data exchange between ADP's German payroll system and government agencies (social insurance carriers, tax authorities, pension funds, health insurance providers).
|
||||
|
||||
## Value Proposition
|
||||
|
||||
- Single repository for 25+ compliance modules — atomic commits, shared libraries, one version
|
||||
- Covers the full lifecycle: generate → validate → transmit → receive → process government messages
|
||||
- Supports dual database modes (H2 for dev/on-prem, Oracle for production multi-tenant)
|
||||
- Automated Wartungswechsel (maintenance version rotation) across past/current/future branches
|
||||
|
||||
## Key Features & Modules
|
||||
|
||||
| Module | Domain | Purpose |
|
||||
|--------|--------|---------|
|
||||
| **eau** | Sick-leave certificates | Electronic work incapacity certificates (eAU) |
|
||||
| **eau-connector** | eAU transport | Elscomfort gateway integration for eAU |
|
||||
| **eubp** | Electronic tax audit | EuBP — Elektronische Übermittlung der Beitragspflichtigen |
|
||||
| **svbea** | Social insurance | SV-Beitragserhebung — contribution assessment notifications |
|
||||
| **babea** | Social insurance | BABEA — Beitragsabrechnung notifications |
|
||||
| **dabpv** | Pension insurance | DaBPV — Datenaustausch Beitragspflichtversicherung |
|
||||
| **svmodules** | SV messages | SVMeldungen — social insurance message generation |
|
||||
| **rvbea** | Pension | RV-BEA — pension insurance notifications |
|
||||
| **dsvv** | SV procedures | DSVV — Datensatz Versicherungsverlauf |
|
||||
| **dsbd** | SV procedures | DSBD — Datensatz Betriebsdaten |
|
||||
| **estatistik** | Statistics | Employment statistics reporting |
|
||||
| **lstbprint** | Tax | Lohnsteuerbescheinigung printing |
|
||||
| **gfmnrgts** | Regulatory | GKV-Finanzmanagement regulatory |
|
||||
| **dls** | Data logistics | Data logistics service |
|
||||
| **doc-gen** | Documents | Document generation |
|
||||
| **eusan-gen** | Sanctions | EU/US sanctions list download & COBOL .DAT conversion |
|
||||
| **blzabgleich** | Banking | Bank code reconciliation |
|
||||
| **taetigkeitsschluessel** | Occupation codes | Activity key management |
|
||||
| **meldezentrale** | Message hub | Central message routing service (Docker-deployed) |
|
||||
| **answering-machine** | Testing | Government response simulator (React + Spring Boot) |
|
||||
| **kernpruefung-rest** | Validation | XML schema validation REST service |
|
||||
|
||||
## Target Users
|
||||
|
||||
- **ADP Germany payroll operations** — automated compliance processing for thousands of employer clients
|
||||
- **ADP developers** — building and maintaining government data exchange modules
|
||||
- **QA teams** — using answering-machine to simulate government responses
|
||||
|
||||
## Deployment Targets
|
||||
|
||||
- **On-premises**: JAR-based deployment via Artifactory (H2 database)
|
||||
- **Cloud (EKS)**: Docker containers for answering-machine, meldezentrale, NATS, kernpruefung-rest
|
||||
- **Kubernetes clusters**: `eks-awsadpworldiat-pr` (DIT), `eks-awsdev6` (dev)
|
||||
|
||||
## Current Version
|
||||
|
||||
`123.4.2` (from `version.json`) — SemVer with `past/current/future` branch rotation.
|
||||
@@ -0,0 +1,120 @@
|
||||
# Paisy — Technology Stack
|
||||
|
||||
## Languages & Runtimes
|
||||
|
||||
| Technology | Version | Usage |
|
||||
|-----------|---------|-------|
|
||||
| Java | 17 (compiler release) | All backend modules |
|
||||
| JavaScript/Node.js | Node 24 (Chainguard) | Answering-machine React frontend |
|
||||
| Groovy | (Jenkins) | Jenkinsfile pipeline scripting |
|
||||
| JavaScript | ES6+ | `gen_trigger.js` — Quidam ISAM trigger generation |
|
||||
| SQL | H2 + Oracle dialects | Database migrations and queries |
|
||||
|
||||
## Build System
|
||||
|
||||
| Tool | Details |
|
||||
|------|---------|
|
||||
| Maven | Multi-module POM, `${revision}` for version injection |
|
||||
| Maven Wrapper | Not used — relies on CI image Maven |
|
||||
| npm | Frontend build for `am-frontend/` |
|
||||
|
||||
### Key Maven Commands
|
||||
|
||||
```bash
|
||||
# Full build
|
||||
mvn clean install -f java/pom.xml --batch-mode -U -Drevision=<version>
|
||||
|
||||
# Single module with dependencies
|
||||
mvn clean install -pl modules/cs-modules/<module> -am -DskipTests
|
||||
|
||||
# Deploy to Artifactory
|
||||
mvn deploy -f java/pom.xml -DskipTests --batch-mode -U -Drevision=<version>
|
||||
```
|
||||
|
||||
## Frameworks & Libraries
|
||||
|
||||
### Core
|
||||
|
||||
| Library | Version | Purpose |
|
||||
|---------|---------|---------|
|
||||
| Spring Boot | 3.5.11 | Application framework |
|
||||
| Spring Shell | 3.3.3 | CLI command dispatch |
|
||||
| Lombok | (managed) | Boilerplate reduction (`@Data`, `@Builder`, `@Slf4j`) |
|
||||
| H2 Database | 2.4.240 | Dev/on-prem embedded database |
|
||||
| Flyway | (Spring Boot managed) | Database migrations |
|
||||
| JPA/Hibernate | (Spring Boot managed) | ORM layer |
|
||||
|
||||
### Data Processing
|
||||
|
||||
| Library | Purpose |
|
||||
|---------|---------|
|
||||
| JAXB | XML marshalling/unmarshalling for GKV data exchange |
|
||||
| Apache Commons CSV | Semicolon-delimited CSV (ISO-8859-1) |
|
||||
| Custom `flatfile-parser` | German flat-file format with `@Datenbaustein`/`@DBField` annotations |
|
||||
|
||||
### Infrastructure
|
||||
|
||||
| Technology | Purpose |
|
||||
|-----------|---------|
|
||||
| NATS JetStream | Message broker (subject: `{bbnr}.{ak}.{app}.{stage}[.{type}]`) |
|
||||
| Docker | Container builds for AM, Meldezentrale, NATS |
|
||||
| Kubernetes (EKS) | Cloud deployment target |
|
||||
| Helm | Kubernetes deployment charts (`ferris-wheel/web-service`) |
|
||||
|
||||
## CI/CD
|
||||
|
||||
| Component | Details |
|
||||
|-----------|---------|
|
||||
| Jenkins | Pipeline-as-code via `Jenkinsfile` |
|
||||
| Jenkins Library | `@Library('adp-jenkins')` — shared pipeline library |
|
||||
| Docker Images | `maven:3.9-jdk-17` (main), `maven:3.8.3-jdk-11` (kernpruefung-rest) |
|
||||
| Artifactory | `repository.esi.adp.com/RD-GERMANY/` — Maven + Docker registry |
|
||||
| SonarQube | Code quality scanning (non-release branches) |
|
||||
| Secrets Scan | `secretsScan()` in pipeline |
|
||||
|
||||
### Pipeline Stages
|
||||
|
||||
1. **Wartungswechsel** — version rotation across past/current/future branches
|
||||
2. **Build** — Maven compile + test for `java/pom.xml`
|
||||
3. **Sonar + Secrets** — quality gate + secrets detection
|
||||
4. **Docker Build** — AM, Meldezentrale, NATS (parallel)
|
||||
5. **Cherry-pick** — auto-propagate merges upward (past→current→future)
|
||||
6. **Deploy** — Artifactory publish + Kubernetes deploy
|
||||
7. **Tag Release** — Git tag on release branches
|
||||
8. **Version Update** — auto-bump patch version
|
||||
9. **EusanGen** — standalone sanctions list update (manual or `eusan/*` branch trigger)
|
||||
|
||||
## Database
|
||||
|
||||
| Mode | Engine | Usage |
|
||||
|------|--------|-------|
|
||||
| Development | H2 (file-based) | Local dev, testing, legacy on-prem |
|
||||
| Production | Oracle | Multi-tenant, shared schema per BBNR |
|
||||
|
||||
### Migration Naming Convention
|
||||
```
|
||||
V{yyyy_MM_dd_HH_mm_ss}__C_{app_revision}_{entity_name}.sql
|
||||
```
|
||||
Separate directories: `db/migration/ORACLE/` and `db/migration/H2/`
|
||||
|
||||
## Encoding
|
||||
|
||||
- Source files: **UTF-8**
|
||||
- CSV files: **ISO-8859-1** (German government standard)
|
||||
- Flat files: **ISO-8859-1** (DSRV/ITSG format)
|
||||
|
||||
## Docker Registry
|
||||
|
||||
| Image | Registry Path |
|
||||
|-------|--------------|
|
||||
| Answering Machine | `docker.repository.esi.adp.com/paisy/answering-machine` |
|
||||
| Meldezentrale | `docker.repository.esi.adp.com/paisy/meldezentrale` |
|
||||
| NATS | `docker.repository.esi.adp.com/paisy/nats` |
|
||||
| Kernprüfung REST | `docker.repository.esi.adp.com/paisy/kernpruefung-rest-service` |
|
||||
|
||||
## Kubernetes Clusters
|
||||
|
||||
| Cluster | Namespace | Purpose |
|
||||
|---------|-----------|---------|
|
||||
| `eks-awsadpworldiat-pr` | `paisyservices-dit` | DIT environment (AM, MZ, NATS) |
|
||||
| `eks-awsdev6` | `pa-kernpruefung-rest-service-dev` | Dev (Kernprüfung REST) |
|
||||
Reference in New Issue
Block a user