From ad276c01f337fc7fb752f1f0f80ee7d82186d515 Mon Sep 17 00:00:00 2001 From: Chris Chen Date: Thu, 25 Jun 2026 17:56:09 -0700 Subject: [PATCH] docs(1099): document Payee1099s/Form1099Boxes schema and seed Form1099 permissions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DB_SCHEMA.md §8: add Form1099Box catalog table, Payee1099 recipient master (with TIN at-rest encryption note), and new FK columns on Expenses / ExpenseSubCategories / ExpenseCategoryGroups; update TOC and Seed Data section - DbSeeder.cs: grant Modules.Form1099 to finance (R/W/D), pastor (R), and board_member (R), mirroring the Form990Report + Disbursements pattern; idempotent (only inserts if row absent, never clobbers admin edits) Co-Authored-By: Claude Opus 4.8 --- API/ROLAC.API/Data/DbSeeder.cs | 5 ++ docs/DB_SCHEMA.md | 96 ++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) diff --git a/API/ROLAC.API/Data/DbSeeder.cs b/API/ROLAC.API/Data/DbSeeder.cs index 0446072..b4d880f 100644 --- a/API/ROLAC.API/Data/DbSeeder.cs +++ b/API/ROLAC.API/Data/DbSeeder.cs @@ -207,6 +207,11 @@ public static class DbSeeder ("finance", Modules.ChurchProfile, true, true, false, false), ("finance", Modules.Disbursements, true, true, true, true), ("finance", Modules.Form990Report, true, false, false, false), + // Form1099 — finance manages recipients and tracks filings; pastor and board_member + // get read-only oversight (same pattern as Form990Report). No Approve semantics. + ("finance", Modules.Form1099, true, true, true, false), + ("pastor", Modules.Form1099, true, false, false, false), + ("board_member", Modules.Form1099, true, false, false, false), // Logs — read-only. System logs are technical (pastor only); audit logs have // governance value, so finance and board members can read them too. diff --git a/docs/DB_SCHEMA.md b/docs/DB_SCHEMA.md index 3e75001..f95248a 100644 --- a/docs/DB_SCHEMA.md +++ b/docs/DB_SCHEMA.md @@ -17,6 +17,9 @@ 6. [Phase 1 — CMS](#6-cms) 7. [Phase 1 — Giving & Donations(奉獻)](#7-giving--donations-奉獻) 8. [Phase 1 — Expense Tracking(支出)](#8-expense-tracking-支出) + - [Form1099Box(1099 欄位目錄)](#form1099box-irs-1099-報告欄位目錄) + - [Payee1099(收款人主檔)](#payee1099-1099-申報收款人主檔) + - [現有表新增欄位(1099 歸屬)](#現有表新增欄位1099-歸屬) 9. [Phase 1 — Prayer Requests(代禱)](#9-prayer-requests-代禱) 10. [Phase 1 — Audit Log](#10-audit-log) 11. [Phase 1 — Notifications](#11-notifications) @@ -704,6 +707,91 @@ Table: MonthlyStatements | UpdatedBy | varchar(450) NOT NULL | FK → AspNetUsers.Id | | **UNIQUE** | (Year, Month) | 每個月只有一份月結報表 | +### Form1099Box(IRS 1099 報告欄位目錄) + +``` +Table: Form1099Boxes +``` + +| 欄位 | 型別 | 說明 | +|------|------|------| +| Id | int PK | | +| BoxCode | varchar(20) NOT NULL UNIQUE | 欄位代碼,如 "NEC-1"、"MISC-1" | +| Name_en | varchar(200) NOT NULL | 英文欄位名稱 | +| Name_zh | varchar(200)? | 中文欄位名稱 | +| FormType | varchar(20) NOT NULL | '1099-NEC' \| '1099-MISC' | +| SortOrder | int NOT NULL DEFAULT 0 | 顯示排序 | +| IsActive | bool NOT NULL DEFAULT true | | +| CreatedAt | timestamp NOT NULL | | +| CreatedBy | varchar(450) NOT NULL | FK → AspNetUsers.Id | +| UpdatedAt | timestamp NOT NULL | | +| UpdatedBy | varchar(450) NOT NULL | FK → AspNetUsers.Id | + +> **說明:** IRS 1099 申報欄位目錄(catalog)。Seed 預設兩個欄位:`NEC-1`(Nonemployee compensation — 非員工報酬,1099-NEC 第 1 欄)與 `MISC-1`(Rents — 租金,1099-MISC 第 1 欄)。此表為唯讀參考資料,僅透過 seed 管理;新增欄位須更新 seed 並重新執行 migration。 + +### Payee1099(1099 申報收款人主檔) + +``` +Table: Payee1099s +``` + +| 欄位 | 型別 | 說明 | +|------|------|------| +| Id | int PK | | +| LegalName | varchar(200) NOT NULL | IRS 法定全名(個人或公司)| +| DisplayName | varchar(200)? | 顯示用簡稱(選填)| +| MemberId | int? | FK → Members.Id,ON DELETE SET NULL。收款人同時為教友時可選填關聯 | +| TaxClassification | varchar(50) NOT NULL | 稅務分類,如 'Individual'、'SoleProprietor'、'Corporation'、'Partnership' 等 | +| Is1099Tracked | bool NOT NULL DEFAULT true | 是否需要申報 1099 | +| TinType | varchar(10)? | 'SSN' \| 'EIN';null = 尚未收到 W-9 | +| **TinEncrypted** | varchar(MAX)? | **TIN 加密密文(使用 ASP.NET Data Protection API 加密靜態儲存,明文永不入庫)** | +| **TinLast4** | varchar(4)? | **TIN 末四碼明文(僅供遮罩顯示用,如 \*\*\*-\*\*-1234)** | +| AddressLine1 | varchar(200)? | | +| AddressLine2 | varchar(200)? | | +| City | varchar(100)? | | +| State | varchar(50)? | | +| Zip | varchar(20)? | | +| Email | varchar(200)? | | +| Phone | varchar(30)? | | +| W9Status | varchar(20) NOT NULL DEFAULT 'Missing' | 'Missing' \| 'Requested' \| 'OnFile' \| 'Expired' | +| W9ReceivedDate | date? | W-9 文件收到日期 | +| W9BlobPath | varchar(500)? | 上傳的 W-9 文件 Azure Blob 路徑 | +| IsActive | bool NOT NULL DEFAULT true | | +| Notes | text? | 內部備注 | +| IsDeleted | bool NOT NULL DEFAULT false | 軟刪除 | +| DeletedAt | timestamp? | | +| DeletedBy | varchar(450)? | FK → AspNetUsers.Id | +| CreatedAt | timestamp NOT NULL | | +| CreatedBy | varchar(450) NOT NULL | FK → AspNetUsers.Id | +| UpdatedAt | timestamp NOT NULL | | +| UpdatedBy | varchar(450) NOT NULL | FK → AspNetUsers.Id | + +> **TIN 靜態加密(Encryption at Rest):** 納稅識別碼(SSN / EIN)屬高敏感個人資料。`TinEncrypted` 欄位儲存使用 ASP.NET Data Protection API(`IDataProtector`)加密後的密文;`TinLast4` 僅儲存末四碼明文供前端遮罩顯示(\*\*\*-\*\*-XXXX)。明文 TIN 永遠不寫入資料庫,也不出現在 Audit Log 快照中。 + +### 現有表新增欄位(1099 歸屬) + +以下欄位由 1099 功能新增至現有表,透過 EF Core Migration 套用: + +**`Expenses`(新增欄位)** + +| 欄位 | 型別 | 說明 | +|------|------|------| +| **PayeeId** | int? | FK → Payee1099s.Id,ON DELETE SET NULL。費用標題層級 1099 收款人歸屬;null = 不申報 1099 | + +**`ExpenseSubCategories`(新增欄位)** + +| 欄位 | 型別 | 說明 | +|------|------|------| +| **Form1099BoxId** | int? | FK → Form1099Boxes.Id,ON DELETE SET NULL。子項目層級 1099 申報欄位映射(優先於大類值)| + +**`ExpenseCategoryGroups`(新增欄位)** + +| 欄位 | 型別 | 說明 | +|------|------|------| +| **Form1099BoxId** | int? | FK → Form1099Boxes.Id,ON DELETE SET NULL。大類層級 1099 申報欄位備援映射 | + +> **有效 1099 欄位解析順序:** `SubCategory.Form1099BoxId ?? Group.Form1099BoxId ?? null`(先取子項目欄位;若為 null 則取大類欄位;仍為 null = 該費用不需申報 1099)。此解析邏輯與 Form 990 行號解析(`SubCategory.Form990LineId ?? Group.Form990LineId ?? "24"`)平行,但語意不同:1099 的 null 代表「不申報」,而 990 的 null 會回退至行 "24"(其他費用)。 + --- ## 9. Prayer Requests(代禱) @@ -1033,6 +1121,14 @@ super_admin, pastor, board_member, coworker_chair, ministry_leader, district_lea Form990Report — 唯讀報表權限,授予角色:finance、pastor、board_member ``` +### Form1099 權限模組 +``` +Form1099 — 1099 收款人管理與申報,授予角色: + finance — Read / Write / Delete(完整管理) + pastor — Read(唯讀總覽) + board_member — Read(唯讀總覽) +``` + ### CmsPages(靜態頁面 Slug) ``` about, vision, service-times, contact