Skip to content

feat(people): add PostgreSQL Employment-history read adapter - #156

Draft
seonghobae wants to merge 60 commits into
feat/employment-history-http-readfrom
feat/employment-history-postgres-adapter
Draft

seonghobae wants to merge 60 commits into
feat/employment-history-http-readfrom
feat/employment-history-postgres-adapter

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 30, 2026 •

Copy link
Copy Markdown
Contributor

Buyer-visible scope

Adds PostgresEmploymentHistoryReadPort behind the governed Person-scoped Employment-history application port. The adapter detaches tenant/Person identity before connection acquisition, structurally binds one PostgreSQL capability, requires a proven non-autocommit connection before cursor acquisition, executes a short read-only tenant-context-bound transaction, reconstructs bitemporal Employment history at the requested knowledge cutoff, and rejects malformed/scope-escaping/visibility-invalid rows. It does not authorize fields itself, mutate HR truth, or make an employment decision.

Current stack authority

Current direct base: #155 4b8fa8e1bd29d941f5889f346014133aaa1c02e9
Current exact head: a701cbdd66699bdf504909077413500b4af0ea51
Protected truth beneath the stack: develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f

The current exact head ordinary-forward adopts #341 through #155/#149/#55. Only canonical parent-owned hire_http.py and the focused dependency-binding regression were adopted; #156-owned PostgreSQL source/tests/SQL contracts remain unchanged. Earlier #333–#337 transport/read hardening is preserved. ADR 0156 remains Proposed.

Historical feature-local HTTP/PostgreSQL workflows remain removed; canonical repository acceptance belongs to Foundation. tests/test_bitemporal_postgres.sh executes production Employment-history SQL against seeded PostgreSQL and covers pre/post-correction cutoffs, half-open recorded boundaries, non-UTC session timezone, foreign-tenant exclusion, and read-only write rejection. Tuple-backed immutable connection_factory, detached exact UUID scalar authority, exact connection.autocommit is False before cursor acquisition, short transaction scope, and post-read scope/cutoff verification remain intact.

No parent/predecessor check or review transfers. After #55/#65/#149/#155 and prerequisites reach protected develop, #156 must ordinary-forward onto then-current protected truth, retarget to develop, and reacquire Foundation—including real PostgreSQL and full People statement/branch coverage—plus Security/SAST/CodeQL/model review and qualifying independent approval.

Keep Draft. No force-push, destructive rebase, self/model approval, routine administrator bypass, gate weakening, mutable-owner source copy, no-op retrigger, predecessor-evidence transfer, synthetic status, feature-local workflow resurrection, or simple Close is authorized.

@coderabbitai

coderabbitai Bot commented Aug 30, 2026 •

Copy link
Copy Markdown

Review Change StackReview Change Stack

📝 Walkthrough

Walkthrough

PostgresEmploymentHistoryReadPort가 추가되었습니다. 포트는 검증된 입력으로 읽기 전용 PostgreSQL 트랜잭션을 실행하고, Employment 이력 행을 재검증한 뒤 불변 결과를 반환합니다. 단위 테스트, 실 PostgreSQL 계약 테스트, ADR 및 추적성 문서가 추가되었습니다.

Changes

Employment 이력 읽기

Layer / File(s) Summary
읽기 포트와 회귀 검증
services/people-api/src/orgmetra_people_api/postgres_employment_history.py, services/people-api/src/orgmetra_people_api/__init__.py, services/people-api/tests/test_postgres_employment_history.py, services/people-api/tests/test_postgres_employment_history_capability_integrity.py, services/people-api/README.md
PostgresEmploymentHistoryReadPort가 불변 연결 capability, UUID와 UTC 시각 검증, 테넌트 범위 SQL, 읽기 전용 트랜잭션, 행 무결성 검증을 제공합니다. 패키지 export와 회귀 테스트가 추가되었습니다.
실 PostgreSQL 계약
tests/test_bitemporal_postgres.sh, services/people-api/README.md
프로덕션 SQL 상수를 추출하여 PostgreSQL에서 tenant context, bitemporal cutoff, 반개방 구간, 외부 테넌트 격리 및 읽기 전용 동작을 검증합니다.
설계 및 추적성 기록
docs/SECURITY.md, docs/TRACEABILITY.md, docs/adr/0156-employment-history-postgres-read.md, docs/adr/README.md, docs/doctoring/postgres-employment-history-read-references.md, docs/traceability/postgres-employment-history-read.md, manifest.json
ADR 0156, 보안 설명, 추적성 매트릭스, 참고문헌, 스택 상태 및 manifest 값이 추가 또는 갱신되었습니다.

Priority: ⬇️ Low

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Caller
  participant PostgresEmploymentHistoryReadPort
  participant PostgreSQL
  Caller->>PostgresEmploymentHistoryReadPort: tenant, person, known_at 전달
  PostgresEmploymentHistoryReadPort->>PostgreSQL: READ COMMITTED, READ ONLY 트랜잭션 시작
  PostgresEmploymentHistoryReadPort->>PostgreSQL: tenant context 및 Employment 쿼리 실행
  PostgreSQL-->>PostgresEmploymentHistoryReadPort: Employment history rows 반환
  PostgresEmploymentHistoryReadPort-->>Caller: 검증된 EmploymentHistoryRecord tuple 반환
Loading

Merge Risk: 🟡 Moderate · up to 667f0

Some valid connection configurations can bypass the adapter’s promised read-only tenant transaction. Enforce an explicit transaction contract before merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 50 functions across 5 files. (8 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목은 PostgreSQL Employment-history read adapter 추가라는 주요 변경 사항을 정확하고 간결하게 설명합니다.
Full details: Docstring Coverage

Explanation

Docstring coverage is 38.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 50 functions across 5 files. (8 skipped: 8 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/employment-history-postgres-adapter

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

현재 exact head 0c397a1f313739a258237109228d27338070a6df 기준으로 재검토해 주세요. 특히 PostgresEmploymentHistoryReadPort의 validated connection_factory가 immutable tuple payload에 구조적으로 결합되어 post-construction replacement와 checked-versus-used drift를 막는지, 그리고 새 focused regression이 그 경계를 정확히 검증하는지 확인 바랍니다.

@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- HEAD ---'
git rev-parse HEAD
printf '%s\n' '--- candidate files ---'
fd -t f . | rg -i 'employment.*history|history.*employment|postgres.*people|people.*postgres'
printf '%s\n' '--- PostgresEmploymentHistoryReadPort references ---'
rg -n -C 5 '\bPostgresEmploymentHistoryReadPort\b' .
printf '%s\n' '--- connection_factory references in employment-history candidates ---'
rg -n -C 5 '\bconnection_factory\b' . -g '*employment*' -g '*Employment*' -g '*postgres*' -g '*Postgres*' || true

Length of output: 76093


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- adapter outline ---'
ast-grep outline people/src/people/infrastructure/employment_history/postgres_read_port.py --items all
printf '%s\n' '--- focused test outline ---'
ast-grep outline people/tests/test_postgres_employment_history_read_port.py --items all
printf '%s\n' '--- adapter source ---'
cat -n people/src/people/infrastructure/employment_history/postgres_read_port.py
printf '%s\n' '--- focused test source ---'
cat -n people/tests/test_postgres_employment_history_read_port.py
printf '%s\n' '--- changed files at reviewed head relative to parent ---'
git diff --name-status 8d7871bd41b98c1f09bade8c17260d8e1b297daf..0c397a1f313739a258237109228d27338070a6df

Length of output: 1462


🏁 Script executed:

#!/bin/bash
set -euo pipefail

adapter='services/people-api/src/orgmetra_people_api/postgres_employment_history.py'
test_file='services/people-api/tests/test_postgres_employment_history_capability_integrity.py'

printf '%s\n' '--- adapter outline ---'
ast-grep outline "$adapter" --items all
printf '%s\n' '--- focused-test outline ---'
ast-grep outline "$test_file" --items all
printf '%s\n' '--- adapter: PostgresEmploymentHistoryReadPort ---'
sed -n '116,190p' "$adapter" | cat -n
printf '%s\n' '--- focused regression ---'
cat -n "$test_file"
printf '%s\n' '--- all factory/property accesses in adapter ---'
rg -n -C 3 '\b(connection_factory|_factory_payload|__getitem__)\b' "$adapter"
printf '%s\n' '--- focused regression diff ---'
git diff --unified=80 8d7871bd41b98c1f09bade8c17260d8e1b297daf..HEAD -- "$test_file" "$adapter"

Length of output: 22189


@seonghobae 0c397a1f313739a258237109228d27338070a6df에서 요청한 범위를 재검토했습니다. 이 범위에서는 새 finding이 없습니다.

PostgresEmploymentHistoryReadPort는 tuple을 상속하고 __slots__ = ()를 선언합니다. 생성자는 callable 검증 후 해당 factory를 tuple payload에 저장합니다. read_employment_history()는 self.connection_factory를 다시 조회하지 않습니다. 대신 tuple.__getitem__(self, 0)으로 payload의 원래 callable을 가져와 실행합니다. 따라서 지원되는 post-construction attribute replacement가 validated capability와 사용 capability를 분리할 수 없습니다.

Focused regression은 필요한 경계를 검증합니다.

  • object.__setattr__(port, "connection_factory", replacement_factory)가 AttributeError를 발생해야 합니다.
  • port.connection_factory is accepted_factory로 노출 view도 원래 callable임을 검증합니다.
  • 실제 빈 read를 수행합니다.
  • accepted_calls == 1로 원래 capability 실행을 검증합니다.
  • replacement_calls == 0로 replacement capability가 실행되지 않았음을 검증합니다.

이 확인은 소스와 테스트 구조를 기준으로 수행했습니다. 이 환경에서는 저장소 테스트를 실행하지 않았습니다. PR은 Draft 상태이며 exact-head hosted Foundation 증거와 독립 승인이 아직 없으므로 승인 또는 병합 권한을 주장하지 않습니다.

You are interacting with an AI system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant