Appearance
Documentation / @kizami/db / leaveGrantProposals
Variable: leaveGrantProposals
constleaveGrantProposals:SQLiteTableWithColumns<{columns: {attendanceRate:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"attendance_rate";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;createdAt:SQLiteColumn<{baseColumn:never;columnType:"SQLiteInteger";data:number;dataType:"number";driverParam:number;enumValues:undefined;generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"created_at";notNull:true;tableName:"leave_grant_proposals"; }, { }, { }>;days:SQLiteColumn<{baseColumn:never;columnType:"SQLiteInteger";data:number;dataType:"number";driverParam:number;enumValues:undefined;generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"days";notNull:true;tableName:"leave_grant_proposals"; }, { }, { }>;decidedAt:SQLiteColumn<{baseColumn:never;columnType:"SQLiteInteger";data:number;dataType:"number";driverParam:number;enumValues:undefined;generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"decided_at";notNull:false;tableName:"leave_grant_proposals"; }, { }, { }>;decidedBy:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"decided_by";notNull:false;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;decisionNote:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"decision_note";notNull:false;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;expiresOn:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"expires_on";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;grantedOn:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"granted_on";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;grantId:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"grant_id";notNull:false;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;id:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:true;name:"id";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;leaveType:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"leave_type";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;proposedAt:SQLiteColumn<{baseColumn:never;columnType:"SQLiteInteger";data:number;dataType:"number";driverParam:number;enumValues:undefined;generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"proposed_at";notNull:true;tableName:"leave_grant_proposals"; }, { }, { }>;status:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"status";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;tenantId:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"tenant_id";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>;userId:SQLiteColumn<{baseColumn:never;columnType:"SQLiteText";data:string;dataType:"string";driverParam:string;enumValues: [string,...string[]];generated:undefined;hasDefault:false;hasRuntimeDefault:false;identity:undefined;isAutoincrement:false;isPrimaryKey:false;name:"user_id";notNull:true;tableName:"leave_grant_proposals"; }, { }, {length:number|undefined; }>; };dialect:"sqlite";name:"leave_grant_proposals";schema:undefined; }>
Defined in: packages/db/src/schema/leave.ts:165
有給付与の「予告」(docs/design/shift-work.md 実装フェーズ4、requirements.md §11)。
付与基準日が近づいたユーザーについて、日次ワーカー(apps/api/src/leave-grant-proposals.ts)が 「◯月◯日に◯日付与される予定」という予告行をここに積む。管理者が内容(特に出勤率の 参考値)を確認して承認したときに初めて leave_grants の行が生まれる — 機械が無条件に 付与を確定させない、という §11 の決定をデータ構造として表したテーブル。
attendanceRate: 出勤率の参考値を JSON で保存する(労基法39条1項の8割出勤要件の 検算材料。最終判断は人が行う)。形は{ periodFrom, periodTo, workingDays, attendedDays, rate, basis }(packages/leave/src/attendance-rate.ts の AttendanceRateReference と同じ)。 算出時点の値をそのまま凍結保存する(後から再計算すると、承認画面で見た数字と 監査上の記録が食い違うため)。status: proposed → approved / rejected。supersededは「予告を経由せずに POST /leave/grants/auto で同じ付与が作られた」場合に予告側を無効化するための状態。grantId: 承認して実際に作られたleave_grants.id(承認前は null)。
判断点(一意制約): (tenant_id, user_id, leave_type, granted_on) は superseded を除いて 高々1件だが、SQLite の部分 UNIQUE INDEX を drizzle スキーマに持たせると マイグレーション生成の互換性(将来の PostgreSQL/D1 分離)に不確実性が残るため、 クエリ層(packages/db/src/queries/leave.ts の findActiveLeaveGrantProposal)で担保する。 DB 側には検索用の通常 index だけを置く(leave_grants の冪等性を listGrantedOnDates で 担保しているのと同じ流儀)。