# 自社期限カレンダー生成スキーマ

このスキーマは `deadline_rules.csv` と自社の原本日付を組み合わせ、期限候補・準備開始日・再確認日を生成するための設計書です。個別会社の日付を推測して埋めるものではありません。

## 1. 設計原則

1. 通知書・結果通知書・CCUS画面・カード券面の日付を原本とする。
2. 法定期限、公式運用上の期限、社内締切を別フィールドにする。
3. 地域差がある項目は全国共通値で上書きせず、所管先ルールを追加する。
4. 根拠URLと確認日がないイベントは「未確認」と表示する。
5. 休日処理を機械的に翌営業日へ動かさない。許可満了日や経審有効期間は前倒し管理する。
6. 出力日は法的判断ではなく管理候補日。提出前に所管先の最新案内で確定する。

## 2. 必須入力

### 会社基本情報 `company`

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `company_id` | string | yes | 社内一意ID。法人番号をそのまま公開データへ出さない |
| `company_name` | string | yes | 表示名 |
| `timezone` | string | yes | `Asia/Tokyo` |
| `fiscal_year_end` | date | yes | 定款・決算書で確認した直近の事業年度終了日 |
| `permit_authority_name` | string | yes | 国土交通大臣許可の管轄地方整備局、または都道府県名 |
| `permit_authority_url` | url | yes | 最新の手引き・申請案内URL |
| `authority_checked_on` | date | yes | 手引きを確認した日 |

### 許可 `permits[]`

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `permit_record_id` | string | yes | 許可単位の社内ID |
| `permit_number` | string | yes | 許可通知書記載。外部共有時はマスキング可 |
| `permit_type` | enum | yes | `minister` / `governor` |
| `permission_classes` | string[] | yes | 一般・特定、業種等 |
| `valid_until` | date | yes | 許可通知書記載の満了日。自己計算値で代替しない |
| `acceptance_start` | date/null | no | 所管行政庁が示す受付開始日。最新手引きから入力 |
| `source_document` | string | yes | 許可通知書のファイル名・保管場所 |
| `verified_on` | date | yes | 原本確認日 |

### 経審 `keishin`

公共工事を発注者から直接請け負わない会社は `applicable=false` とする。

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `applicable` | boolean | yes | 年次受審管理の対象か |
| `result_notice_id` | string/null | 条件付 | 現在有効な結果通知書の管理ID |
| `assessment_base_date` | date/null | 条件付 | 結果通知書記載の審査基準日 |
| `notice_received_on` | date/null | no | 参考値。失効計算の起点にはしない |
| `authority_name` | string/null | 条件付 | 審査行政庁 |
| `authority_guide_url` | url/null | 条件付 | 2026年7月1日以降用の最新手引き |
| `standard_processing_days` | integer/null | no | 行政庁公表値がある場合のみ。推測で埋めない |
| `reservation_required` | boolean/null | no | 最新手引きで確認 |
| `verified_on` | date/null | 条件付 | 結果通知書・手引き確認日 |

### 許可変更イベント `permit_changes[]`

30日届・2週間届は、把握日ではなく変更事実発生日を期限計算の起点にする。事実発生日が不明なイベントは期限を生成せず、人へ差し戻す。

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `change_event_id` | string | yes | 変更イベント単位の社内ID |
| `rule_id` | enum | yes | `PERMIT-CHANGE-30D` / `PERMIT-CHANGE-14D` |
| `fact_date` | date/null | yes | 辞令、退職日、登記日等で確認した変更事実発生日。期限計算の唯一の起点 |
| `detected_on` | date | yes | 社内で変更を把握した日。監査・相談用で、期限計算には使わない |
| `evidence_document` | string/null | yes | 事実発生日を確認した原本・社内記録 |
| `authority_consulted_on` | date/null | no | 事実発生日不明・期限超過時の相談日 |
| `verified_on` | date | yes | 原本確認日 |

### CCUS事業者・管理者ID `ccus_business`

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `applicable` | boolean | yes | CCUS利用の有無 |
| `business_id` | string/null | 条件付 | 外部共有時はマスキング可 |
| `business_valid_until` | date/null | 条件付 | ログイン画面表示の事業者登録有効期限 |
| `responsible_email_checked_on` | date/null | 条件付 | 登録責任者メールの確認日 |
| `admin_ids` | object[] | 条件付 | 有償管理者ID単位で管理 |

`admin_ids[]` の項目:

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `admin_id_masked` | string | yes | 末尾4桁などの社内識別子 |
| `id_type` | enum | yes | `first` / `additional` / `site_manager` / `other` |
| `valid_until` | date | yes | CCUS画面表示値 |
| `original_registration_month` | `YYYY-MM` | no | 請求時期照合用。画面・請求書で確認 |
| `invoice_due_date` | date/null | no | 請求書が届いたら入力。計算候補より優先 |
| `renewal_intent` | enum | yes | `renew` / `stop` / `undecided` |
| `verified_on` | date | yes | 画面確認日 |

### CCUS技能者カード `ccus_workers[]`

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `worker_id` | string | yes | 社内従業員ID。氏名・生年月日を配布データに含めない |
| `card_id_masked` | string | yes | 末尾4桁など |
| `card_valid_until` | date | yes | カード券面の有効期限 |
| `card_term_category` | enum | yes | `standard_10y` / `age60plus_15y` / `no_identity_3y` / `unknown` |
| `category_evidence` | string | yes | 申請時区分またはカード券面確認メモ。現在年齢で再判定しない |
| `registered_contact_checked_on` | date | no | 案内メール・住所の確認日 |
| `verified_on` | date | yes | 券面確認日 |

### 営業日カレンダー `business_calendar`

| フィールド | 型 | 必須 | 説明 |
|---|---|---:|---|
| `weekend_days` | integer[] | yes | ISO曜日。例: `[6,7]` |
| `national_holidays` | date[] | yes | 対象年の日本の祝日 |
| `authority_closures` | date[] | no | 年末年始・臨時閉庁など、所管行政庁の案内から入力 |
| `company_closures` | date[] | no | 社内の提出作業ができない日 |

## 3. 地域・発注者別の追加ルール

### 許可行政庁上書き `authority_overrides[]`

| フィールド | 型 | 説明 |
|---|---|---|
| `authority_name` | string | 行政庁名 |
| `rule_id` | string | `deadline_rules.csv` のルールID |
| `acceptance_offset` | duration/null | 例: `P2M`。公式手引きで確認した場合のみ |
| `submission_methods` | string[] | 窓口・郵送・JCIP等 |
| `holiday_policy` | string | 公式記載を要約 |
| `official_url` | url | 根拠URL |
| `checked_on` | date | 確認日 |
| `expires_on` | date/null | 手引きの適用期限がある場合 |

### 入札参加資格 `bid_qualifications[]`

入札参加資格は全国共通ルールへ混ぜず、発注機関ごとに記録する。

| フィールド | 型 | 説明 |
|---|---|---|
| `issuer_name` | string | 国・自治体・団体名 |
| `qualification_name` | string | 制度名 |
| `current_valid_until` | date/null | 現資格の有効期限 |
| `application_start` | datetime/null | 定期・随時受付開始 |
| `application_end` | datetime/null | 時刻指定も保持 |
| `official_url` | url | 公式公告・手引き |
| `checked_on` | date | 確認日 |
| `status` | enum | `confirmed` / `not_announced` / `needs_review` |

## 4. 日付計算関数

### `add_calendar_months(date, months, preserve_eom=true)`

- 月数は日数換算しない。
- 起点が月末なら、移動先の月末を返す。
- 起点の日が移動先に存在しない場合は移動先の月末を返す。
- 例示: 12月31日に4か月を加えると翌年4月30日。
- 出力後、所管行政庁の公式例・休日処理で確定する。
- 経審の期間末計算では `preserve_eom=false` とし、19か月後の応当日（応当日がなければ月末）の前日を期限候補にする。

### `subtract_calendar_days(date, days)`

- 許可更新の「30日前」は暦日で引く。
- 営業日換算へ置き換えない。

### `previous_open_day(date, business_calendar)`

- 社内締切候補の前倒しにだけ使う。
- 法定期限そのものを書き換えない。

### `next_open_day(date, business_calendar)`

- 行政庁が公式に休日繰越を明示したルールだけに使用する。
- 明示がなければ `confirmation_required=true` のままにする。

## 5. ルール適用

### 決算変更届

```text
legal_due_candidate = add_calendar_months(fiscal_year_end, 4, preserve_eom=true)
internal_due = previous_open_day(legal_due_candidate - 14 days)
recommended_start = fiscal_year_end + 1 day
confirmation_required = true
```

14日前は社内推奨値であり法定期限ではない。行政庁の休日処理と必要書類を確認後に `confirmed_due_date` を記録する。

### 建設業許可更新

```text
legal_due_candidate = valid_until - 30 calendar days
recommended_start = valid_until - 120 calendar days
acceptance_start = authority_override.acceptance_start if confirmed else null
internal_due = previous_open_day(legal_due_candidate - 14 days)
```

`valid_until` が複数ある場合は許可レコードごとにイベントを作る。許可の一本化を推測しない。

### 許可変更届

```text
if fact_date is null:
    legal_or_official_due = null
    confirmation_required = true
    status = "needs_human_review"
else if rule_id == "PERMIT-CHANGE-14D":
    legal_due_candidate = fact_date + 14 calendar days
else if rule_id == "PERMIT-CHANGE-30D":
    legal_due_candidate = fact_date + 30 calendar days
```

- `detected_on` が `fact_date` より後でも、期限を把握日から数え直さない。
- 事実発生日が不明、または期限超過の可能性がある場合は、自己判断で日付を補わず所管行政庁へ確認する。
- 休日処理は行政庁の公式案内を確認し、社内締切候補だけを前開庁日へ置く。

### 経審

```text
nineteen_month_anniversary = add_calendar_months(assessment_base_date, 19, preserve_eom=false)
current_result_expiry_candidate = nineteen_month_anniversary - 1 calendar day
next_cycle_start = add_calendar_months(assessment_base_date, 12, preserve_eom=false)
result_needed_by = previous_open_day(current_result_expiry_candidate - safety_buffer_days)
```

- `safety_buffer_days` は社内値。例示値を全国ルールに固定しない。
- `notice_received_on` は失効計算に使わない。
- 期間末候補は、建設業法施行規則第18条の2の「契約締結日の1年7月前の日の直後の事業年度終了の日以降」という条件に対応させた管理値。例として審査基準日が3月31日なら翌年10月30日を候補とする。結果通知書・発注者・審査行政庁の案内に異なる表示がある場合は、その表示を優先して確認する。
- 新結果の取得見込み日は、所管行政庁の公表処理期間と予約可能日が入力済みの場合だけ生成する。

### CCUS事業者登録

```text
recommended_start = business_valid_until - 6 calendar months
recommended_application_due = business_valid_until - 1 calendar month
official_due = business_valid_until
```

`business_valid_until` はCCUS画面表示値。登録日からの再計算で上書きしない。

### CCUS管理者ID

```text
intent_check_start = admin_id.valid_until - 2 calendar months
official_due = invoice_due_date if present else null
invoice_expected_month = original_registration_month + 1 calendar month
payment_candidate = day 10 of original_registration_month + 2 calendar months
```

請求書が届いた時点で `invoice_due_date` を入力し、候補日を上書きする。

### CCUS技能者カード

```text
recommended_start = card_valid_until - 6 calendar months
official_due = card_valid_until
```

期限区分は説明用であり、期限日を再計算するために使わない。券面日付を正とする。

## 6. 出力 `calendar_events[]`

| フィールド | 型 | 説明 |
|---|---|---|
| `event_id` | string | `company_id + rule_id + object_id + due_date` のハッシュ等 |
| `rule_id` | string | 適用ルール |
| `object_type` | enum | `company` / `permit` / `keishin` / `ccus_business` / `ccus_admin_id` / `worker_card` / `bid_qualification` |
| `object_id` | string | 対象レコードID |
| `event_name` | string | 表示名 |
| `recommended_start` | date/null | 準備開始 |
| `internal_due` | date/null | 社内締切 |
| `legal_or_official_due` | date/null | 法定・公式期限候補 |
| `confirmed_due_date` | date/null | 最新公式情報で確定した日 |
| `confirmation_required` | boolean | 未確認ならtrue |
| `risk_level` | enum | `critical` / `high` / `normal` / `info` |
| `source_url` | url | 根拠URL |
| `source_checked_on` | date | 根拠確認日 |
| `evidence_ref` | string | 通知書・画面キャプチャ等の保管参照 |
| `status` | enum | `planned` / `in_progress` / `submitted` / `accepted` / `completed` / `overdue_needs_advice` |
| `owner` | string | 社内担当 |
| `notes` | string | 地域差・補正・照会記録 |

## 7. 通知の既定案

通知日は法定期限ではなく社内運用値。会社ごとに調整する。

- 許可更新・CCUS事業者更新: 180、120、90、60、30、14、7日前
- 決算変更届: 決算翌日、期限60、30、14、7日前
- 経審: 前回結果失効日の180、120、90、60、30日前。新結果受領まで完了扱いにしない
- 管理者ID: 意思確認開始、請求書受領時、支払期限14、7、3日前
- 技能者カード: 180、90、60、30日前。本人と所属事業者の双方へ通知
- `confirmation_required=true` のイベント: 期限90日前までに公式URLを再確認するタスクを追加

## 8. バリデーション

次の場合は日付を生成せず、エラーまたは要確認にする。

- 許可満了日の証拠が許可通知書でない。
- 経審の審査基準日が未入力なのに通知受領日だけがある。
- CCUS事業者有効期限を登録日だけから作ろうとしている。
- 技能者カード期限を現在年齢から推測しようとしている。
- 公式URLまたは確認日がない。
- 地域差がある受付開始日を全国一律値で上書きしようとしている。
- 法定期限候補が過去日になった。`overdue_needs_advice` とし、翌営業日へ自動移動しない。

## 9. 例示データの扱い

説明用に「3月31日決算なら7月末」「許可満了30日前」などを表示しても、配布本体には特定会社の確定日として保存しない。テストデータには `is_example=true` を付け、本番出力から除外する。

## 10. 情報管理

- 外部配布するCSVには、許可番号、CCUS ID、技能者氏名、生年月日、メールアドレスを含めない。
- 原本の画像・PDFはアクセス制御された社内保管先に置き、カレンダーには参照IDだけを持つ。
- 退職者のカード情報や担当者メールは、社内の保存方針に従って削除・更新する。
