@aiquants/daily-report 0.6.0 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -38
- package/dist/client.d.mts +9 -3
- package/dist/client.d.ts +9 -3
- package/dist/client.js +4 -4
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +4 -4
- package/dist/client.mjs.map +1 -1
- package/dist/server.d.mts +34 -4
- package/dist/server.d.ts +34 -4
- package/dist/server.js +6 -6
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +6 -6
- package/dist/server.mjs.map +1 -1
- package/package.json +3 -3
- package/src/client/components/daily-report-detail-list.tsx +28 -6
- package/src/client/components/daily-report-list.tsx +25 -4
- package/src/client/components/daily-report-resolved-content.tsx +28 -4
- package/src/client/config-context.tsx +2 -0
- package/src/client/contexts/daily-report-action-context.tsx +5 -1
- package/src/client/route-helpers.ts +8 -2
- package/src/server/authz.spec.ts +57 -0
- package/src/server/authz.ts +99 -0
- package/src/server/handlers.ts +5 -4
- package/src/server/service.ts +31 -13
- package/src/server.ts +1 -0
package/dist/server.d.mts
CHANGED
|
@@ -1239,10 +1239,11 @@ type DailyReportServiceConfig = {
|
|
|
1239
1239
|
/** クロスワーカー epoch ストア (facade が生成して注入)。 */
|
|
1240
1240
|
epochs: EpochStore;
|
|
1241
1241
|
/**
|
|
1242
|
-
* 下書きラベル名 (
|
|
1243
|
-
*
|
|
1242
|
+
* 下書きラベル名 (単一または配列で指定可能)。
|
|
1243
|
+
* 消費アプリ側で自 DB のラベル名や作成区分の候補名 ("下書き", "DRAFT" など) を注入できる。
|
|
1244
1244
|
*/
|
|
1245
|
-
draftLabelName
|
|
1245
|
+
draftLabelName?: string;
|
|
1246
|
+
draftLabelNames?: string[];
|
|
1246
1247
|
/** SSE Redis Stream キー (既定 "daily-report:sse-stream")。 */
|
|
1247
1248
|
streamKey?: string;
|
|
1248
1249
|
/** SSE Stream の MAXLEN (既定 10000)。 */
|
|
@@ -1363,6 +1364,35 @@ declare class DailyReportSseReader {
|
|
|
1363
1364
|
private _stopLoop;
|
|
1364
1365
|
}
|
|
1365
1366
|
|
|
1367
|
+
type AuthzResourceItem = {
|
|
1368
|
+
resourceKey: string;
|
|
1369
|
+
name: string;
|
|
1370
|
+
description?: string | null;
|
|
1371
|
+
};
|
|
1372
|
+
type DailyReportSourceTypeInput = {
|
|
1373
|
+
key: string;
|
|
1374
|
+
name: string;
|
|
1375
|
+
description?: string | null;
|
|
1376
|
+
includeCommentResource?: boolean;
|
|
1377
|
+
};
|
|
1378
|
+
/**
|
|
1379
|
+
* Dynamically builds neutral Authz resource definitions from provided source type inputs.
|
|
1380
|
+
* 指定されたソース種別定義から中立な認可リソース定義リストを生成するファクトリ。
|
|
1381
|
+
*/
|
|
1382
|
+
declare function defineDailyReportAuthzResources(sources?: DailyReportSourceTypeInput[]): AuthzResourceItem[];
|
|
1383
|
+
/**
|
|
1384
|
+
* Ensures all daily-report standard resources exist in the authz TMResource table idempotently.
|
|
1385
|
+
* authz データベース内に日報機能の標準認可リソースが存在することを自動保証(冪等シード)する処理。
|
|
1386
|
+
*/
|
|
1387
|
+
declare function seedDailyReportAuthzResources(db: unknown, authzTables: {
|
|
1388
|
+
TMResource: unknown;
|
|
1389
|
+
}, opts: {
|
|
1390
|
+
appKey: string;
|
|
1391
|
+
actor?: string;
|
|
1392
|
+
sources?: DailyReportSourceTypeInput[];
|
|
1393
|
+
resources?: AuthzResourceItem[];
|
|
1394
|
+
}): Promise<void>;
|
|
1395
|
+
|
|
1366
1396
|
/**
|
|
1367
1397
|
* Generates a SHA-256 ETag for the given data.
|
|
1368
1398
|
* 指定されたデータの SHA-256 ETag を生成します。
|
|
@@ -1524,4 +1554,4 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
|
|
|
1524
1554
|
streamKey: string;
|
|
1525
1555
|
};
|
|
1526
1556
|
|
|
1527
|
-
export { type DailyReportAuthResult, type DailyReportAuthenticate, type DailyReportCommentRow, type DailyReportCommentTable, type DailyReportDb, type DailyReportEncodeUserId, type DailyReportExternalSource, type DailyReportHandlersConfig, type DailyReportHubLabelTable, type DailyReportHubRow, type DailyReportHubTable, type DailyReportInternalRow, type DailyReportInternalTable, type DailyReportLabelTable, type DailyReportRedisBlockingClient, type DailyReportRedisClient, type DailyReportRedisProvider, type DailyReportResolveUserId, type DailyReportServerConfig, type DailyReportService, type DailyReportServiceConfig, DailyReportSseReader, type DailyReportSseReaderConfig, type DailyReportTables, type DailyReportUserStatusRow, type DailyReportUserStatusTable, type DailyReportUserTable, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportSchema, generateETag, isStreamIdLte, jsonResponseWithETag, transformJsonArray };
|
|
1557
|
+
export { type AuthzResourceItem, type DailyReportAuthResult, type DailyReportAuthenticate, type DailyReportCommentRow, type DailyReportCommentTable, type DailyReportDb, type DailyReportEncodeUserId, type DailyReportExternalSource, type DailyReportHandlersConfig, type DailyReportHubLabelTable, type DailyReportHubRow, type DailyReportHubTable, type DailyReportInternalRow, type DailyReportInternalTable, type DailyReportLabelTable, type DailyReportRedisBlockingClient, type DailyReportRedisClient, type DailyReportRedisProvider, type DailyReportResolveUserId, type DailyReportServerConfig, type DailyReportService, type DailyReportServiceConfig, type DailyReportSourceTypeInput, DailyReportSseReader, type DailyReportSseReaderConfig, type DailyReportTables, type DailyReportUserStatusRow, type DailyReportUserStatusTable, type DailyReportUserTable, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportAuthzResources, defineDailyReportSchema, generateETag, isStreamIdLte, jsonResponseWithETag, seedDailyReportAuthzResources, transformJsonArray };
|
package/dist/server.d.ts
CHANGED
|
@@ -1239,10 +1239,11 @@ type DailyReportServiceConfig = {
|
|
|
1239
1239
|
/** クロスワーカー epoch ストア (facade が生成して注入)。 */
|
|
1240
1240
|
epochs: EpochStore;
|
|
1241
1241
|
/**
|
|
1242
|
-
* 下書きラベル名 (
|
|
1243
|
-
*
|
|
1242
|
+
* 下書きラベル名 (単一または配列で指定可能)。
|
|
1243
|
+
* 消費アプリ側で自 DB のラベル名や作成区分の候補名 ("下書き", "DRAFT" など) を注入できる。
|
|
1244
1244
|
*/
|
|
1245
|
-
draftLabelName
|
|
1245
|
+
draftLabelName?: string;
|
|
1246
|
+
draftLabelNames?: string[];
|
|
1246
1247
|
/** SSE Redis Stream キー (既定 "daily-report:sse-stream")。 */
|
|
1247
1248
|
streamKey?: string;
|
|
1248
1249
|
/** SSE Stream の MAXLEN (既定 10000)。 */
|
|
@@ -1363,6 +1364,35 @@ declare class DailyReportSseReader {
|
|
|
1363
1364
|
private _stopLoop;
|
|
1364
1365
|
}
|
|
1365
1366
|
|
|
1367
|
+
type AuthzResourceItem = {
|
|
1368
|
+
resourceKey: string;
|
|
1369
|
+
name: string;
|
|
1370
|
+
description?: string | null;
|
|
1371
|
+
};
|
|
1372
|
+
type DailyReportSourceTypeInput = {
|
|
1373
|
+
key: string;
|
|
1374
|
+
name: string;
|
|
1375
|
+
description?: string | null;
|
|
1376
|
+
includeCommentResource?: boolean;
|
|
1377
|
+
};
|
|
1378
|
+
/**
|
|
1379
|
+
* Dynamically builds neutral Authz resource definitions from provided source type inputs.
|
|
1380
|
+
* 指定されたソース種別定義から中立な認可リソース定義リストを生成するファクトリ。
|
|
1381
|
+
*/
|
|
1382
|
+
declare function defineDailyReportAuthzResources(sources?: DailyReportSourceTypeInput[]): AuthzResourceItem[];
|
|
1383
|
+
/**
|
|
1384
|
+
* Ensures all daily-report standard resources exist in the authz TMResource table idempotently.
|
|
1385
|
+
* authz データベース内に日報機能の標準認可リソースが存在することを自動保証(冪等シード)する処理。
|
|
1386
|
+
*/
|
|
1387
|
+
declare function seedDailyReportAuthzResources(db: unknown, authzTables: {
|
|
1388
|
+
TMResource: unknown;
|
|
1389
|
+
}, opts: {
|
|
1390
|
+
appKey: string;
|
|
1391
|
+
actor?: string;
|
|
1392
|
+
sources?: DailyReportSourceTypeInput[];
|
|
1393
|
+
resources?: AuthzResourceItem[];
|
|
1394
|
+
}): Promise<void>;
|
|
1395
|
+
|
|
1366
1396
|
/**
|
|
1367
1397
|
* Generates a SHA-256 ETag for the given data.
|
|
1368
1398
|
* 指定されたデータの SHA-256 ETag を生成します。
|
|
@@ -1524,4 +1554,4 @@ declare function createDailyReportServer(config: DailyReportServerConfig): {
|
|
|
1524
1554
|
streamKey: string;
|
|
1525
1555
|
};
|
|
1526
1556
|
|
|
1527
|
-
export { type DailyReportAuthResult, type DailyReportAuthenticate, type DailyReportCommentRow, type DailyReportCommentTable, type DailyReportDb, type DailyReportEncodeUserId, type DailyReportExternalSource, type DailyReportHandlersConfig, type DailyReportHubLabelTable, type DailyReportHubRow, type DailyReportHubTable, type DailyReportInternalRow, type DailyReportInternalTable, type DailyReportLabelTable, type DailyReportRedisBlockingClient, type DailyReportRedisClient, type DailyReportRedisProvider, type DailyReportResolveUserId, type DailyReportServerConfig, type DailyReportService, type DailyReportServiceConfig, DailyReportSseReader, type DailyReportSseReaderConfig, type DailyReportTables, type DailyReportUserStatusRow, type DailyReportUserStatusTable, type DailyReportUserTable, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportSchema, generateETag, isStreamIdLte, jsonResponseWithETag, transformJsonArray };
|
|
1557
|
+
export { type AuthzResourceItem, type DailyReportAuthResult, type DailyReportAuthenticate, type DailyReportCommentRow, type DailyReportCommentTable, type DailyReportDb, type DailyReportEncodeUserId, type DailyReportExternalSource, type DailyReportHandlersConfig, type DailyReportHubLabelTable, type DailyReportHubRow, type DailyReportHubTable, type DailyReportInternalRow, type DailyReportInternalTable, type DailyReportLabelTable, type DailyReportRedisBlockingClient, type DailyReportRedisClient, type DailyReportRedisProvider, type DailyReportResolveUserId, type DailyReportServerConfig, type DailyReportService, type DailyReportServiceConfig, type DailyReportSourceTypeInput, DailyReportSseReader, type DailyReportSseReaderConfig, type DailyReportTables, type DailyReportUserStatusRow, type DailyReportUserStatusTable, type DailyReportUserTable, type EpochStore, type ExternalReportFields, type RedisStreamMessage, SqlResultCache, type SqlResultCacheQueryOptions, type StreamEntry, createDailyReportHandlers, createDailyReportServer, createDailyReportService, createEpochStore, defineDailyReportAuthzResources, defineDailyReportSchema, generateETag, isStreamIdLte, jsonResponseWithETag, seedDailyReportAuthzResources, transformJsonArray };
|
package/dist/server.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use strict";var Se=Object.defineProperty;var Ve=Object.getOwnPropertyDescriptor;var Ze=Object.getOwnPropertyNames;var et=Object.prototype.hasOwnProperty;var tt=(r,t)=>{for(var i in t)Se(r,i,{get:t[i],enumerable:!0})},rt=(r,t,i,l)=>{if(t&&typeof t=="object"||typeof t=="function")for(let m of Ze(t))!et.call(r,m)&&m!==i&&Se(r,m,{get:()=>t[m],enumerable:!(l=Ve(t,m))||l.enumerable});return r};var nt=r=>rt(Se({},"__esModule",{value:!0}),r);var gt={};tt(gt,{DailyReportSseReader:()=>me,SqlResultCache:()=>pe,createDailyReportHandlers:()=>Ne,createDailyReportServer:()=>yt,createDailyReportService:()=>Ee,createEpochStore:()=>Ie,defineDailyReportSchema:()=>mt,generateETag:()=>Re,isStreamIdLte:()=>ye,jsonResponseWithETag:()=>Z,transformJsonArray:()=>pt});module.exports=nt(gt);var Ie=r=>({async getEpoch(t){try{let i=await r?.getClient();if(!i)return 0;let l=await i.get(t);return l?Number(l):0}catch{return 0}},async incrementEpoch(t){try{let i=await r?.getClient();if(!i)return;await i.incr(t)}catch{}}}),pe=class{constructor(t,i){this.config=t;this.epochStore=i;this.buckets=new Map;this.inFlight=new Map;this.invalidate=t=>{this.buckets.delete(t),this.inFlight.delete(t)};this.getOrFetch=async t=>{let{cacheKey:i,forceRefresh:l,snapshot:m}=t,h=this.buckets.get(i);if(l&&(this.buckets.delete(i),this.inFlight.delete(i)),!l&&h&&h.expireAt>Date.now())if(t.epochKey){let c=await this.epochStore.getEpoch(t.epochKey);if(h.epoch===c)return m?h.records.map(j=>structuredClone(j)):h.records;this.buckets.delete(i)}else return m?h.records.map(c=>structuredClone(c)):h.records;if(!l&&this.inFlight.has(i)){let c=await this.inFlight.get(i);return m?c.map(j=>structuredClone(j)):c}let O;O=(async()=>{let c=await t.fetcher();if(l||this.inFlight.get(i)===O){let j=Date.now()+(t.ttlMsOverride??this.config.defaultTtlMs),p=t.epochKey?await this.epochStore.getEpoch(t.epochKey):0;this.buckets.set(i,{records:c,expireAt:j,epoch:p}),this.buckets.size>500&&this.cleanExpired()}return c})(),l||this.inFlight.set(i,O);try{let c=await O;return m?c.map(j=>structuredClone(j)):c}finally{this.inFlight.delete(i)}};this.flush=t=>{this.buckets.delete(t),this.inFlight.delete(t)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=t=>{for(let i of this.buckets.keys())i.startsWith(t)&&this.buckets.delete(i);for(let i of this.inFlight.keys())i.startsWith(t)&&this.inFlight.delete(i)}}cleanExpired(){let t=Date.now();for(let[i,l]of this.buckets.entries())l.expireAt<=t&&this.buckets.delete(i)}};var at=/^\d{4}-\d{2}-\d{2}$/,it=/^\d{4}\/\d{2}\/\d{2}$/,Pe=r=>r<10?`0${r}`:`${r}`,Be=r=>{if(Number.isNaN(r.getTime()))return null;let t=r.getFullYear(),i=Pe(r.getMonth()+1),l=Pe(r.getDate());return`${t}-${i}-${l}`},G=r=>{if(r==null)return null;if(r instanceof Date)return Be(r);let t=r.trim();if(t==="")return null;if(at.test(t))return t;if(it.test(t))return t.replaceAll("/","-");let i=new Date(t);return Be(i)};var te=(r,t,i=console)=>{let l=m=>typeof m=="string"?[`${t} ${m}`]:[t,m];return{debug:(m,...h)=>{r<=0&&i.debug(...l(m),...h)},info:(m,...h)=>{r<=1&&i.info(...l(m),...h)},warn:(m,...h)=>{r<=2&&i.warn(...l(m),...h)},error:(m,...h)=>{r<=3&&i.error(...l(m),...h)}}};var o=require("zod"),st=o.z.object({name:o.z.string().nullish(),affiliation:o.z.string().nullish()}),ot=o.z.object({name:o.z.string().nullish(),text:o.z.string().nullish(),color:o.z.string().nullish()}),lt=o.z.object({id:o.z.number(),name:o.z.string().nullish(),color:o.z.string().nullish()}),Ue=o.z.object({id:o.z.number(),userId:o.z.string().nullish(),userName:o.z.string().nullish(),content:o.z.string().nullish(),createdAt:o.z.string().nullish(),isMine:o.z.boolean()}),_e=o.z.object({reportHubId:o.z.number(),date:o.z.string().nullish(),createdAt:o.z.string().nullish(),author:o.z.string().nullish(),userId:o.z.string().nullish(),sourceType:o.z.string().nullish(),employeeName:o.z.string().nullish(),updatedBy:o.z.string().nullish(),updatedAt:o.z.string().nullish(),category:o.z.string().nullish(),creationCategory:o.z.string().nullish(),visitTimeFrom:o.z.string().nullish(),visitTimeTo:o.z.string().nullish(),customerName:o.z.string().nullish(),interviewers:o.z.array(st),subject:o.z.string().nullish(),content:o.z.string().nullish(),comments:o.z.array(ot),isRead:o.z.boolean(),isStarred:o.z.boolean(),labels:o.z.array(lt),commentItems:o.z.array(Ue)}),dt=o.z.object({type:o.z.literal("connected")}),be=o.z.object({type:o.z.literal("status-update"),reportHubId:o.z.number(),statusType:o.z.enum(["star","read"]),value:o.z.boolean(),clientTempId:o.z.string(),recipientRawUserId:o.z.number().optional()}),Ce=o.z.object({type:o.z.literal("comment-add"),reportHubId:o.z.number(),comment:Ue,clientTempId:o.z.string()}),Ae=o.z.object({type:o.z.literal("comment-delete"),reportHubId:o.z.number(),commentId:o.z.number(),clientTempId:o.z.string()}),Te=o.z.object({type:o.z.literal("report-create"),reportHubId:o.z.number(),report:_e,clientTempId:o.z.string(),recipientRawUserId:o.z.number().optional()}),ve=o.z.object({type:o.z.literal("report-update"),reportHubId:o.z.number(),report:_e,clientTempId:o.z.string(),recipientRawUserId:o.z.number().optional()}),Me=o.z.object({type:o.z.literal("report-publish"),reportHubId:o.z.number(),report:_e,clientTempId:o.z.string(),recipientRawUserId:o.z.number().optional()}),xe=o.z.object({type:o.z.literal("report-delete"),reportHubId:o.z.number(),clientTempId:o.z.string()}),He=o.z.discriminatedUnion("type",[dt,be,Ce,Ae,Te,ve,Me,xe]);var Ye=require("crypto"),Re=r=>{let t=JSON.stringify(r);return`"${(0,Ye.createHash)("sha256").update(t).digest("hex")}"`};var ut=te(1,"[Response]"),Z=(r,t,i,l=200,m=ut)=>{let h=Re(i),O=r.headers.get("If-None-Match");m.info(`[jsonResponseWithETag] ETag: ${h}, If-None-Match: ${O}`);let c=new Headers({"Content-Type":"application/json","Cache-Control":"private, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","Content-Security-Policy":"default-src 'none'",ETag:h});return t&&c.append("Set-Cookie",t),r.method==="GET"&&l===200&&O===h?new Response(null,{status:304,headers:c}):new Response(JSON.stringify(i),{status:l,headers:c})};var qe=require("events");var ye=(r,t)=>{let[i,l]=r.split("-").map(Number),[m,h]=t.split("-").map(Number);return i!==m?i<m:l<=h},me=class{constructor(t){this.config=t;this._emitter=new qe.EventEmitter;this._state="idle";this._refCount=0;this._lastId="0-0";this._emitter.setMaxListeners(0),this._logger=t.logger??te(1,"[SSE Reader]")}subscribe(t,i){return this._emitter.on("entry",t),i&&this._emitter.on("error",i),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",t),i&&this._emitter.removeListener("error",i),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="0-0"}async _startLoop(){for(;this._state==="stopping";)await new Promise(t=>setTimeout(t,50));if(this._state!=="running"){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(t){this._state="idle",this._emitter.emit("error",t instanceof Error?t:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitter.emit("error",new Error("Failed to create Redis client for SSE reader"));return}this._client.on("error",t=>{this._logger.error("Redis client error:",t)});try{for(;this._state==="running"&&this._client?.isOpen;){let t=await this._client.xRead([{key:this.config.streamKey,id:this._lastId}],{BLOCK:5e3,COUNT:100});if(t)for(let i of t)for(let l of i.messages){this._lastId=l.id;try{let m=l.message?.data?JSON.parse(l.message.data):null,h=m?.type;if((h==="report-create"||h==="report-delete"||h==="report-publish")&&this.config.cache.invalidatePrefix("daily-report:ids"),h==="comment-add"||h==="comment-delete"||h==="status-update"){let O=m?.reportHubId;typeof O=="number"&&(this.config.cache.invalidate(`daily-report:detail:${O}`),this.config.cache.invalidatePrefix(`daily-report:detail:${O}:user:`))}}catch{}this._emitter.emit("entry",{id:l.id,message:l.message})}}}catch(t){!(t?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",t),this._emitter.emit("error",t))}finally{if(this._client?.isOpen)try{await this._client.quit()}catch{}this._client=void 0,this._state="idle",this._refCount>0&&this._startLoop()}}}async _stopLoop(){if(this._state==="running"){if(this._state="stopping",this._client?.isOpen)try{await this._client.quit()}catch{}for(;this._state!=="idle";)await new Promise(t=>setTimeout(t,50))}}};var M=(r,t)=>new Response(JSON.stringify(r),{status:t?.status??200,headers:{"Content-Type":"application/json"}});function Ne(r){let{authenticate:t,service:i,encodeUserId:l,redis:m,sseReader:h,streamKey:O}=r,c=r.loginRedirectPath??"/auth/login",j=r.logger??te(3,"[DailyReportAPI]"),p=r.logger??te(1,"[DailyReportSSE]"),g=async({request:A})=>{let{user:P,cookie:I}=await t(A,{failureRedirect:c}),L=new Headers;I&&L.append("Set-Cookie",I);let C=null;P&&(C=await i.getUserIdByExternalId(P.id));let S=C?l(C):null;return{data:{user:P,userId:S},headers:L}},k={"business-date":async(A,P,I,L)=>{let C=G(A.searchParams.get("businessDate")),S=A.searchParams.get("forceRefresh")==="true";if(!C)return Z(I,P,{error:{message:"Invalid business date"}},400);let B=await i.getDailyReportsByBusinessDateByExternalId(C,L.id,{forceRefresh:S});return Z(I,P,{businessDate:C,reports:B},200)},ids:async(A,P,I,L)=>{let C=A.searchParams.get("forceRefresh")==="true",S=await i.getDailyReportIdsByExternalId(L.id,{forceRefresh:C});return Z(I,P,{ids:S},200)},report:async(A,P,I,L)=>{let C=A.searchParams.get("reportHubId"),S=A.searchParams.get("forceRefresh")==="true",B=C?Number.parseInt(C,10):NaN;if(!Number.isFinite(B)||B<=0)return Z(I,P,{error:{message:"Invalid reportHubId"}},400);let x=await i.getDailyReportDetailByIdByExternalId(B,L.id,{snapshot:!0,forceRefresh:S});return x?Z(I,P,{report:x},200):Z(I,P,{error:{message:"Report not found"}},404)}};return{index:{loader:g},api:{loader:async({request:A,params:P})=>{let{user:I,cookie:L}=await t(A,{failureRedirect:null}),C=L??null;if(!I)return Z(A,C,{error:{message:"Unauthorized"}},401);if(A.method!=="GET")return Z(A,C,{error:{message:"Method not allowed"}},405);let S=P.endpoint??"",B=k[S];if(!B)return Z(A,C,{error:{message:"Unknown endpoint"}},404);let x=Date.now();try{let w=new URL(A.url);return await B(w,C,A,I)}catch(w){let q=Date.now()-x,Q=w instanceof Error?w:new Error(String(w));return j.error(`500 endpoint=${S} elapsed=${q}ms name=${Q.name} code=${"code"in Q?Q.code:"N/A"} message=${Q.message}`),j.error("Stack:",Q.stack),Z(A,C,{error:{message:"Internal Server Error"}},500)}},action:async({request:A,params:P})=>{let{user:I}=await t(A,{failureRedirect:null});if(!I)return M({error:"Unauthorized"},{status:401});if(P.endpoint!=="action")return M({error:"Unknown endpoint"},{status:404});let C=await i.getUserIdByExternalId(I.id);if(!C)return M({error:"User not found"},{status:404});let S=await A.formData(),B=S.get("intent"),x=S.get("reportHubId"),w=x?Number(x):NaN,q=S.get("businessDate"),Q=Number(S.get("operationTimestamp")),N=S.get("clientTempId");if(!N)return M({error:"clientTempId required"},{status:400});if(B!=="create"&&(!w||Number.isNaN(w)))return M({error:"Invalid reportHubId"},{status:400});switch(B){case"create":{if(!q)return M({error:"businessDate required"},{status:400});let y=await i.createDailyReport(C,q,N);return M({status:"OK",intent:"create",report:y,reportHubId:String(y.reportHubId),clientTempId:N})}case"update":{let y=S.get("title"),$=S.get("content");try{return await i.updateDailyReport(w,C,{title:y,content:$},N),M({status:"OK",intent:"update",reportHubId:String(w),clientTempId:N})}catch(T){if(T instanceof Error){if(T.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(T.message==="Not Found")return M({error:"Report not found"},{status:404})}throw T}}case"publish":try{let y=await i.publishDailyReport(w,C,N);return M({status:"OK",intent:"publish",reportHubId:String(w),clientTempId:N,report:y})}catch(y){if(y instanceof Error){if(y.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(y.message==="Not Found")return M({error:"Report not found"},{status:404})}throw y}case"delete":try{return await i.deleteDailyReport(w,C,N),M({status:"OK",intent:"delete",reportHubId:String(w),clientTempId:N})}catch(y){if(y instanceof Error){if(y.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(y.message==="Not Found")return M({error:"Report not found"},{status:404})}throw y}case"toggleStar":{let y=S.get("isStarred");if(y===null)return M({error:"isStarred required"},{status:400});let $=y==="true",T=await i.setStarStatus(C,w,q,$,N);return M({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:T.isStarred,isRead:T.isRead},operationTimestamp:Q,reportHubId:String(w),clientTempId:N})}case"toggleRead":{let y=S.get("isRead");if(y===null)return M({error:"isRead required"},{status:400});let $=y==="true",T=await i.setReadStatus(C,w,q,$,N);return M({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:T.isStarred,isRead:T.isRead},operationTimestamp:Q,reportHubId:String(w),clientTempId:N})}case"addComment":{let y=S.get("content");if(!y)return M({error:"Content required"},{status:400});let $=await i.addComment(C,w,y,q,N),T={...$,userId:$.userId};return M({status:"OK",intent:"addComment",newComment:T,reportHubId:String(w),clientTempId:N})}case"deleteComment":{let y=Number(S.get("commentId"));if(!y||Number.isNaN(y))return M({error:"Invalid commentId"},{status:400});try{return await i.deleteComment(C,w,y,q,N),M({status:"OK",reportHubId:String(w),deletedCommentId:String(y),clientTempId:N})}catch($){if($ instanceof Error){if($.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if($.message==="Not Found")return M({error:"Comment not found"},{status:404})}throw $}}case"clearCache":return await i.clearCache(),M({status:"OK",intent:"clearCache"});default:return M({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:A,params:P})=>{let{user:I}=await t(A,{failureRedirect:null});if(!I)return new Response("Unauthorized",{status:401});let L=await i.getUserIdByExternalId(I.id);if(!L)return new Response("Forbidden",{status:403});if(P.endpoint!=="updates")return new Response("Not Found",{status:404});let S=new URL(A.url).searchParams.get("lastEventId")||A.headers.get("Last-Event-ID"),B=new TextEncoder,x=null,w=null,q=null,Q=!1,N=()=>{if(!Q){if(Q=!0,w&&(clearInterval(w),w=null),q&&(q(),q=null),x)try{x.desiredSize!==null&&x.close()}catch{}finally{x=null}Q=!1}},y=(T,K)=>{if(K.data)try{let v=JSON.parse(K.data),W=He.safeParse(v);if(!W.success){p.error("SSE message validation failed:",W.error.format());return}let ee=W.data,ae=typeof v.recipientRawUserId=="number"?v.recipientRawUserId:void 0;if(ee.type==="status-update"){if(ae===void 0||ae!==L)return}else if(ae!==void 0&&ae!==L)return;let le;if("recipientRawUserId"in v){let{recipientRawUserId:ke,...ie}=v;le=JSON.stringify(ie)}else le=K.data;x&&x.desiredSize!==null&&x.enqueue(B.encode(`id: ${T}
|
|
2
|
-
data: ${
|
|
1
|
+
"use strict";var _e=Object.defineProperty;var rt=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var at=Object.prototype.hasOwnProperty;var st=(r,e)=>{for(var s in e)_e(r,s,{get:e[s],enumerable:!0})},ot=(r,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let c of nt(e))!at.call(r,c)&&c!==s&&_e(r,c,{get:()=>e[c],enumerable:!(i=rt(e,c))||i.enumerable});return r};var it=r=>ot(_e({},"__esModule",{value:!0}),r);var Dt={};st(Dt,{DailyReportSseReader:()=>me,SqlResultCache:()=>pe,createDailyReportHandlers:()=>Le,createDailyReportServer:()=>Rt,createDailyReportService:()=>$e,createEpochStore:()=>Ae,defineDailyReportAuthzResources:()=>ze,defineDailyReportSchema:()=>bt,generateETag:()=>we,isStreamIdLte:()=>ye,jsonResponseWithETag:()=>ee,seedDailyReportAuthzResources:()=>gt,transformJsonArray:()=>ft});module.exports=it(Dt);var Ae=r=>({async getEpoch(e){try{let s=await r?.getClient();if(!s)return 0;let i=await s.get(e);return i?Number(i):0}catch{return 0}},async incrementEpoch(e){try{let s=await r?.getClient();if(!s)return;await s.incr(e)}catch{}}}),pe=class{constructor(e,s){this.config=e;this.epochStore=s;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.getOrFetch=async e=>{let{cacheKey:s,forceRefresh:i,snapshot:c}=e,y=this.buckets.get(s);if(i&&(this.buckets.delete(s),this.inFlight.delete(s)),!i&&y&&y.expireAt>Date.now())if(e.epochKey){let p=await this.epochStore.getEpoch(e.epochKey);if(y.epoch===p)return c?y.records.map(z=>structuredClone(z)):y.records;this.buckets.delete(s)}else return c?y.records.map(p=>structuredClone(p)):y.records;if(!i&&this.inFlight.has(s)){let p=await this.inFlight.get(s);return c?p.map(z=>structuredClone(z)):p}let q;q=(async()=>{let p=await e.fetcher();if(i||this.inFlight.get(s)===q){let z=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs),u=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0;this.buckets.set(s,{records:p,expireAt:z,epoch:u}),this.buckets.size>500&&this.cleanExpired()}return p})(),i||this.inFlight.set(s,q);try{let p=await q;return c?p.map(z=>structuredClone(z)):p}finally{this.inFlight.delete(s)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let s of this.buckets.keys())s.startsWith(e)&&this.buckets.delete(s);for(let s of this.inFlight.keys())s.startsWith(e)&&this.inFlight.delete(s)}}cleanExpired(){let e=Date.now();for(let[s,i]of this.buckets.entries())i.expireAt<=e&&this.buckets.delete(s)}};var lt=/^\d{4}-\d{2}-\d{2}$/,dt=/^\d{4}\/\d{2}\/\d{2}$/,He=r=>r<10?`0${r}`:`${r}`,Ye=r=>{if(Number.isNaN(r.getTime()))return null;let e=r.getFullYear(),s=He(r.getMonth()+1),i=He(r.getDate());return`${e}-${s}-${i}`},V=r=>{if(r==null)return null;if(r instanceof Date)return Ye(r);let e=r.trim();if(e==="")return null;if(lt.test(e))return e;if(dt.test(e))return e.replaceAll("/","-");let s=new Date(e);return Ye(s)};var re=(r,e,s=console)=>{let i=c=>typeof c=="string"?[`${e} ${c}`]:[e,c];return{debug:(c,...y)=>{r<=0&&s.debug(...i(c),...y)},info:(c,...y)=>{r<=1&&s.info(...i(c),...y)},warn:(c,...y)=>{r<=2&&s.warn(...i(c),...y)},error:(c,...y)=>{r<=3&&s.error(...i(c),...y)}}};var l=require("zod"),ut=l.z.object({name:l.z.string().nullish(),affiliation:l.z.string().nullish()}),ct=l.z.object({name:l.z.string().nullish(),text:l.z.string().nullish(),color:l.z.string().nullish()}),pt=l.z.object({id:l.z.number(),name:l.z.string().nullish(),color:l.z.string().nullish()}),qe=l.z.object({id:l.z.number(),userId:l.z.string().nullish(),userName:l.z.string().nullish(),content:l.z.string().nullish(),createdAt:l.z.string().nullish(),isMine:l.z.boolean()}),Te=l.z.object({reportHubId:l.z.number(),date:l.z.string().nullish(),createdAt:l.z.string().nullish(),author:l.z.string().nullish(),userId:l.z.string().nullish(),sourceType:l.z.string().nullish(),employeeName:l.z.string().nullish(),updatedBy:l.z.string().nullish(),updatedAt:l.z.string().nullish(),category:l.z.string().nullish(),creationCategory:l.z.string().nullish(),visitTimeFrom:l.z.string().nullish(),visitTimeTo:l.z.string().nullish(),customerName:l.z.string().nullish(),interviewers:l.z.array(ut),subject:l.z.string().nullish(),content:l.z.string().nullish(),comments:l.z.array(ct),isRead:l.z.boolean(),isStarred:l.z.boolean(),labels:l.z.array(pt),commentItems:l.z.array(qe)}),mt=l.z.object({type:l.z.literal("connected")}),De=l.z.object({type:l.z.literal("status-update"),reportHubId:l.z.number(),statusType:l.z.enum(["star","read"]),value:l.z.boolean(),clientTempId:l.z.string(),recipientRawUserId:l.z.number().optional()}),ve=l.z.object({type:l.z.literal("comment-add"),reportHubId:l.z.number(),comment:qe,clientTempId:l.z.string()}),Me=l.z.object({type:l.z.literal("comment-delete"),reportHubId:l.z.number(),commentId:l.z.number(),clientTempId:l.z.string()}),xe=l.z.object({type:l.z.literal("report-create"),reportHubId:l.z.number(),report:Te,clientTempId:l.z.string(),recipientRawUserId:l.z.number().optional()}),Ne=l.z.object({type:l.z.literal("report-update"),reportHubId:l.z.number(),report:Te,clientTempId:l.z.string(),recipientRawUserId:l.z.number().optional()}),Ee=l.z.object({type:l.z.literal("report-publish"),reportHubId:l.z.number(),report:Te,clientTempId:l.z.string(),recipientRawUserId:l.z.number().optional()}),ke=l.z.object({type:l.z.literal("report-delete"),reportHubId:l.z.number(),clientTempId:l.z.string()}),Oe=l.z.discriminatedUnion("type",[mt,De,ve,Me,xe,Ne,Ee,ke]);var Ke=require("crypto"),we=r=>{let e=JSON.stringify(r);return`"${(0,Ke.createHash)("sha256").update(e).digest("hex")}"`};var yt=re(1,"[Response]"),ee=(r,e,s,i=200,c=yt)=>{let y=we(s),q=r.headers.get("If-None-Match");c.info(`[jsonResponseWithETag] ETag: ${y}, If-None-Match: ${q}`);let p=new Headers({"Content-Type":"application/json","Cache-Control":"private, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","Content-Security-Policy":"default-src 'none'",ETag:y});return e&&p.append("Set-Cookie",e),r.method==="GET"&&i===200&&q===y?new Response(null,{status:304,headers:p}):new Response(JSON.stringify(s),{status:i,headers:p})};var Fe=require("events");var ye=(r,e)=>{let[s,i]=r.split("-").map(Number),[c,y]=e.split("-").map(Number);return s!==c?s<c:i<=y},me=class{constructor(e){this.config=e;this._emitter=new Fe.EventEmitter;this._state="idle";this._refCount=0;this._lastId="0-0";this._emitter.setMaxListeners(0),this._logger=e.logger??re(1,"[SSE Reader]")}subscribe(e,s){return this._emitter.on("entry",e),s&&this._emitter.on("error",s),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),s&&this._emitter.removeListener("error",s),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="0-0"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitter.emit("error",e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitter.emit("error",new Error("Failed to create Redis client for SSE reader"));return}this._client.on("error",e=>{this._logger.error("Redis client error:",e)});try{for(;this._state==="running"&&this._client?.isOpen;){let e=await this._client.xRead([{key:this.config.streamKey,id:this._lastId}],{BLOCK:5e3,COUNT:100});if(e)for(let s of e)for(let i of s.messages){this._lastId=i.id;try{let c=i.message?.data?JSON.parse(i.message.data):null,y=c?.type;if((y==="report-create"||y==="report-delete"||y==="report-publish")&&this.config.cache.invalidatePrefix("daily-report:ids"),y==="comment-add"||y==="comment-delete"||y==="status-update"){let q=c?.reportHubId;typeof q=="number"&&(this.config.cache.invalidate(`daily-report:detail:${q}`),this.config.cache.invalidatePrefix(`daily-report:detail:${q}:user:`))}}catch{}this._emitter.emit("entry",{id:i.id,message:i.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitter.emit("error",e))}finally{if(this._client?.isOpen)try{await this._client.quit()}catch{}this._client=void 0,this._state="idle",this._refCount>0&&this._startLoop()}}}async _stopLoop(){if(this._state==="running"){if(this._state="stopping",this._client?.isOpen)try{await this._client.quit()}catch{}for(;this._state!=="idle";)await new Promise(e=>setTimeout(e,50))}}};var x=(r,e)=>new Response(JSON.stringify(r),{status:e?.status??200,headers:{"Content-Type":"application/json"}});function Le(r){let{authenticate:e,service:s,encodeUserId:i,redis:c,sseReader:y,streamKey:q}=r,p=r.loginRedirectPath??"/auth/login",z=r.logger??re(3,"[DailyReportAPI]"),u=r.logger??re(1,"[DailyReportSSE]"),g=async({request:_})=>{let{user:U,cookie:B}=await e(_,{failureRedirect:p}),S=new Headers;B&&S.append("Set-Cookie",B);let w=null;U&&(w=await s.getUserIdByExternalId(U.id));let A=w?i(w):null;return{data:{user:U,userId:A},headers:S}},$={"business-date":async(_,U,B,S)=>{let w=V(_.searchParams.get("businessDate")),A=_.searchParams.get("forceRefresh")==="true";if(!w)return ee(B,U,{error:{message:"Invalid business date"}},400);let H=await s.getDailyReportsByBusinessDateByExternalId(w,S.id,{forceRefresh:A});return ee(B,U,{businessDate:w,reports:H},200)},ids:async(_,U,B,S)=>{let w=_.searchParams.get("forceRefresh")==="true",A=await s.getDailyReportIdsByExternalId(S.id,{forceRefresh:w});return ee(B,U,{ids:A},200)},report:async(_,U,B,S)=>{let w=_.searchParams.get("reportHubId"),A=_.searchParams.get("forceRefresh")==="true",H=w?Number.parseInt(w,10):NaN;if(!Number.isFinite(H)||H<=0)return ee(B,U,{error:{message:"Invalid reportHubId"}},400);let M=await s.getDailyReportDetailByIdByExternalId(H,S.id,{snapshot:!0,forceRefresh:A});return M?ee(B,U,{report:M},200):ee(B,U,{error:{message:"Report not found"}},404)}};return{index:{loader:g},api:{loader:async({request:_,params:U})=>{let{user:B,cookie:S}=await e(_,{failureRedirect:null}),w=S??null;if(!B)return ee(_,w,{error:{message:"Unauthorized"}},401);if(_.method!=="GET")return ee(_,w,{error:{message:"Method not allowed"}},405);let A=U.endpoint??"",H=$[A];if(!H)return ee(_,w,{error:{message:"Unknown endpoint"}},404);let M=Date.now();try{let I=new URL(_.url);return await H(I,w,_,B)}catch(I){let Y=Date.now()-M,F=I instanceof Error?I:new Error(String(I));return z.error(`500 endpoint=${A} elapsed=${Y}ms name=${F.name} code=${"code"in F?F.code:"N/A"} message=${F.message}`),z.error("Stack:",F.stack),ee(_,w,{error:{message:"Internal Server Error"}},500)}},action:async({request:_,params:U})=>{let{user:B}=await e(_,{failureRedirect:null});if(!B)return x({error:"Unauthorized"},{status:401});if(U.endpoint!=="action")return x({error:"Unknown endpoint"},{status:404});let w=await s.getUserIdByExternalId(B.id);if(!w)return x({error:"User not found"},{status:404});let A=await _.formData(),H=A.get("intent"),M=A.get("reportHubId"),I=M?Number(M):NaN,Y=A.get("businessDate"),F=Number(A.get("operationTimestamp")),N=A.get("clientTempId");if(H==="clearCache")return await s.clearCache(),x({status:"OK",intent:"clearCache"});if(!N)return x({error:"clientTempId required"},{status:400});if(H!=="create"&&(!I||Number.isNaN(I)))return x({error:"Invalid reportHubId"},{status:400});switch(H){case"create":{if(!Y)return x({error:"businessDate required"},{status:400});let R=await s.createDailyReport(w,Y,N);return x({status:"OK",intent:"create",report:R,reportHubId:String(R.reportHubId),clientTempId:N})}case"update":{let R=A.get("title"),C=A.get("content");try{return await s.updateDailyReport(I,w,{title:R,content:C},N),x({status:"OK",intent:"update",reportHubId:String(I),clientTempId:N})}catch(E){if(E instanceof Error){if(E.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(E.message==="Not Found")return x({error:"Report not found"},{status:404})}throw E}}case"publish":try{let R=await s.publishDailyReport(I,w,N);return x({status:"OK",intent:"publish",reportHubId:String(I),clientTempId:N,report:R})}catch(R){if(R instanceof Error){if(R.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(R.message==="Not Found")return x({error:"Report not found"},{status:404})}throw R}case"delete":try{return await s.deleteDailyReport(I,w,N),x({status:"OK",intent:"delete",reportHubId:String(I),clientTempId:N})}catch(R){if(R instanceof Error){if(R.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(R.message==="Not Found")return x({error:"Report not found"},{status:404})}throw R}case"toggleStar":{let R=A.get("isStarred");if(R===null)return x({error:"isStarred required"},{status:400});let C=R==="true",E=await s.setStarStatus(w,I,Y,C,N);return x({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:E.isStarred,isRead:E.isRead},operationTimestamp:F,reportHubId:String(I),clientTempId:N})}case"toggleRead":{let R=A.get("isRead");if(R===null)return x({error:"isRead required"},{status:400});let C=R==="true",E=await s.setReadStatus(w,I,Y,C,N);return x({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:E.isStarred,isRead:E.isRead},operationTimestamp:F,reportHubId:String(I),clientTempId:N})}case"addComment":{let R=A.get("content");if(!R)return x({error:"Content required"},{status:400});let C=await s.addComment(w,I,R,Y,N),E={...C,userId:C.userId};return x({status:"OK",intent:"addComment",newComment:E,reportHubId:String(I),clientTempId:N})}case"deleteComment":{let R=Number(A.get("commentId"));if(!R||Number.isNaN(R))return x({error:"Invalid commentId"},{status:400});try{return await s.deleteComment(w,I,R,Y,N),x({status:"OK",reportHubId:String(I),deletedCommentId:String(R),clientTempId:N})}catch(C){if(C instanceof Error){if(C.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(C.message==="Not Found")return x({error:"Comment not found"},{status:404})}throw C}}default:return x({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:_,params:U})=>{let{user:B}=await e(_,{failureRedirect:null});if(!B)return new Response("Unauthorized",{status:401});let S=await s.getUserIdByExternalId(B.id);if(!S)return new Response("Forbidden",{status:403});if(U.endpoint!=="updates")return new Response("Not Found",{status:404});let A=new URL(_.url).searchParams.get("lastEventId")||_.headers.get("Last-Event-ID"),H=new TextEncoder,M=null,I=null,Y=null,F=!1,N=()=>{if(!F){if(F=!0,I&&(clearInterval(I),I=null),Y&&(Y(),Y=null),M)try{M.desiredSize!==null&&M.close()}catch{}finally{M=null}F=!1}},R=(E,L)=>{if(L.data)try{let T=JSON.parse(L.data),Q=Oe.safeParse(T);if(!Q.success){u.error("SSE message validation failed:",Q.error.format());return}let te=Q.data,ae=typeof T.recipientRawUserId=="number"?T.recipientRawUserId:void 0;if(te.type==="status-update"){if(ae===void 0||ae!==S)return}else if(ae!==void 0&&ae!==S)return;let ue;if("recipientRawUserId"in T){let{recipientRawUserId:Pe,...Ie}=T;ue=JSON.stringify(Ie)}else ue=L.data;M&&M.desiredSize!==null&&M.enqueue(H.encode(`id: ${E}
|
|
2
|
+
data: ${ue}
|
|
3
3
|
|
|
4
|
-
`))}catch(
|
|
4
|
+
`))}catch(T){u.error(`[SSE:${S}] processEntry error:`,T)}},C=new ReadableStream({async start(E){M=E,I=setInterval(()=>{try{M&&M.desiredSize!==null?M.enqueue(H.encode(`: keep-alive
|
|
5
5
|
|
|
6
|
-
`)):N()}catch{N()}},5e3),
|
|
6
|
+
`)):N()}catch{N()}},5e3),_.signal.addEventListener("abort",()=>{N()});let L=A||"0-0";if(Y=y.subscribe(T=>{ye(T.id,L)||(L=T.id,R(T.id,T.message))},T=>{u.error(`[SSE:${S}] Fan-Out reader error:`,T),N()}),!A)try{let T=await c?.getClient();if(T){let Q=await T.xRevRange(q,"+","-",{COUNT:1});Q.length>0&&!ye(Q[0].id,L)&&(L=Q[0].id)}}catch{}if(M&&M.desiredSize!==null){let T=`data: ${JSON.stringify({type:"connected"})}
|
|
7
7
|
|
|
8
|
-
`,
|
|
9
|
-
${v}`:v;x.enqueue(B.encode(W))}if(S)try{let v=await m?.getClient();if(v){let W=await v.xRange(O,S,"+",{COUNT:1e3});for(let ee of W)ee.id!==S&&(ye(ee.id,K)||(K=ee.id,y(ee.id,ee.message)))}}catch(v){p.error(`[SSE:${L}] catch-up xRange error:`,v)}},cancel(){N()}});return new Response($,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}}}}var a=require("drizzle-orm");var ne=r=>(0,a.getColumns)(r);function Ee(r){let{db:t,tables:i,userTable:l,resolveUserId:m,encodeUserId:h,redis:O,cache:c,epochs:j}=r,{hub:p,internal:g,comment:k,label:F,hubLabel:X,userStatus:E}=i,A=r.externalSources??[],P=r.draftLabelName,I=r.logger??te(1,"[DailyReportService]"),L="daily-report:ids",C=r.idsTtlMs??18e4,S="daily-report:ids:epoch",B="daily-report:business-date:",x=r.businessDateTtlMs??3e5,w="daily-report:date-epoch:",q="daily-report:detail-epoch:",Q=r.streamKey??"daily-report:sse-stream",N=r.streamMaxLen??1e4,y=e=>j.incrementEpoch(e),$=async(e,n)=>{let d=await O?.getClient();if(!d){I.warn(`[SSE] Redis client unavailable (${n})`);return}let u=Date.now();try{await d.xAdd(Q,"*",{data:JSON.stringify(e)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:N}});let f=Date.now()-u;f>1e3&&I.warn(`[SSE] Slow publish (${n}): ${f}ms`)}catch(f){I.error(`[SSE] Redis publish failed (${n}):`,f)}},T=(e,n)=>{if(!e)return null;let d=e instanceof Date?e:new Date(e);if(Number.isNaN(d.getTime()))return typeof e=="string"?e:null;let u=n==="YYYY-MM-DD HH:mm:ss"?{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}:{year:"numeric",month:"2-digit",day:"2-digit"};return(n==="YYYY-MM-DD HH:mm:ss"?d.toLocaleString("ja-JP",u):d.toLocaleDateString("ja-JP",u)).replace(/\//g,"-")},K=e=>e==null||e===""?null:/^\d+$/.test(e)?h(Number(e)):e,v=()=>{let e={};for(let n of A)e[`ext_${n.sourceType}`]=ne(n.table);return e},W=e=>{let n=e;for(let d of A)n=n.leftJoin(d.table,(0,a.and)((0,a.eq)(p.sourceType,d.sourceType),(0,a.eq)(p.sourceIdNum,d.idColumn)));return n},ee=(e,n)=>{let{hub:d,internal:u}=e,f=d.summary,b=[],R=null,_=null,U=null,z=null,H=null,V=null,re=[],J=A.find(D=>D.sourceType===d.sourceType),oe=J?e[`ext_${J.sourceType}`]:void 0;if(J&&oe){let D=J.mapRow(oe);D.content!==void 0&&(f=D.content),D.employeeName!==void 0&&(V=D.employeeName),D.category!==void 0&&(R=D.category),D.creationCategory!==void 0&&(_=D.creationCategory),D.visitTimeFrom!==void 0&&(U=D.visitTimeFrom),D.visitTimeTo!==void 0&&(z=D.visitTimeTo),D.customerName!==void 0&&(H=D.customerName),D.interviewers!==void 0&&(b=D.interviewers),D.comments!==void 0&&(re=D.comments)}else d.sourceType==="Internal"&&u&&(f=u.body);let ce=e.labels??[],Y=e.comments??[];return{reportHubId:d.id,date:T(d.businessDate,"YYYY-MM-DD"),author:e.creatorName??K(d.createdBy)??"",userId:d.userId?h(d.userId):"",sourceType:d.sourceType??"Internal",createdAt:T(d.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:T(d.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:K(d.updatedBy),employeeName:V??e.creatorName??K(d.createdBy),category:R,creationCategory:_,visitTimeFrom:U,visitTimeTo:z,customerName:H,interviewers:b,subject:d.title,content:f,comments:re,isRead:e.isRead??!1,isStarred:e.isStarred??!1,labels:ce.map(D=>({id:D.id,name:D.name,color:D.color})),commentItems:Y.map(D=>({...D,userId:h(D.userId),isMine:n?D.userId===n:!1}))}},ae=async e=>{let n=(0,a.aliasedTable)(X,"draft_label");return(await t.select({reportHubId:p.id,businessDate:p.businessDate,sourceType:p.sourceType}).from(p).leftJoin(n,(0,a.and)((0,a.eq)(n.hubId,p.id),(0,a.eq)(n.labelId,t.select({id:F.id}).top(1).from(F).where((0,a.eq)(F.name,P))))).where((0,a.and)((0,a.isNull)(p.deletedAt),(0,a.or)((0,a.eq)(p.userId,e),(0,a.isNull)(n.hubId)))).orderBy((0,a.desc)(p.businessDate),(0,a.desc)(p.id))).map(u=>({...u,businessDate:T(u.businessDate,"YYYY-MM-DD")}))},le=async e=>(await W(t.select({hub:ne(p),internal:ne(g),creatorName:l.displayName,...v()}).from(p)).leftJoin(g,(0,a.eq)(p.id,g.hubId)).leftJoin(l,(0,a.eq)(p.userId,l.id)).where((0,a.and)((0,a.eq)(p.businessDate,a.sql`${e}`),(0,a.isNull)(p.deletedAt))).orderBy((0,a.desc)(p.id))).map(d=>ee(d)),ke=e=>`${B}${e}`,ie=new Map,he=async e=>{if(!r.disableUserIdCache&&ie.has(e))return ie.get(e)??null;let n=await m(e);return n!==null&&!r.disableUserIdCache&&ie.set(e,n),n},Oe=async(e,{forceRefresh:n=!1,snapshot:d=!1,ttlMsOverride:u}={})=>{let f=await he(e);if(!f)return[];let b=`${L}:user:${f}`;return c.getOrFetch({cacheKey:b,fetcher:async()=>await ae(f),forceRefresh:n,snapshot:d,ttlMsOverride:u??C,epochKey:S})},Fe=(e,{forceRefresh:n=!1,snapshot:d=!1,ttlMsOverride:u}={})=>{let f=G(e);return f?c.getOrFetch({cacheKey:ke(f),fetcher:()=>le(f),forceRefresh:n,snapshot:d,ttlMsOverride:u??x}):Promise.resolve([])},de=null,se=async()=>{if(de!==null)return de;let[e]=await t.select({id:F.id}).top(1).from(F).where((0,a.eq)(F.name,P));return e?(de=e.id,de):null},ze=async(e,n,{forceRefresh:d=!1,snapshot:u=!1,ttlMsOverride:f}={})=>{let b=await he(n);if(!b)return[];let R=G(e);if(!R)return[];let _=`daily-report:date:${R}:user:${b}`;return c.getOrFetch({cacheKey:_,fetcher:async()=>{let U=await se(),z=(0,a.aliasedTable)(X,"draft_label"),H=await W(t.select({hub:ne(p),internal:ne(g),isRead:E.isRead,isStarred:E.isStarred,creatorName:l.displayName,...v()}).from(p)).leftJoin(g,(0,a.eq)(p.id,g.hubId)).leftJoin(E,(0,a.and)((0,a.eq)(p.id,E.hubId),(0,a.eq)(E.userId,b))).leftJoin(z,(0,a.and)((0,a.eq)(z.hubId,p.id),(0,a.eq)(z.labelId,U??-1))).leftJoin(l,(0,a.eq)(p.userId,l.id)).where((0,a.and)((0,a.eq)(p.businessDate,a.sql`${R}`),(0,a.isNull)(p.deletedAt),(0,a.or)((0,a.eq)(p.userId,b),(0,a.isNull)(z.hubId)))).orderBy((0,a.desc)(p.id));if(H.length===0)return[];let V=H.map(Y=>Y.hub.id),re=await t.select({hubId:X.hubId,id:F.id,name:F.name,color:F.color}).from(X).innerJoin(F,(0,a.eq)(X.labelId,F.id)).where((0,a.inArray)(X.hubId,V)),J=await t.select({hubId:k.hubId,id:k.id,body:k.body,createdAt:k.createdAt,userId:k.userId,userName:l.displayName}).from(k).leftJoin(l,(0,a.eq)(k.userId,l.id)).where((0,a.inArray)(k.hubId,V)).orderBy((0,a.asc)(k.createdAt)),oe=new Map,ce=new Map;for(let Y of re){let D=oe.get(Y.hubId);D||(D=[],oe.set(Y.hubId,D)),D.push({id:Y.id,name:Y.name,color:Y.color})}for(let Y of J){let D=ce.get(Y.hubId);D||(D=[],ce.set(Y.hubId,D)),D.push({id:Y.id,content:Y.body,createdAt:T(Y.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:Y.userId,userName:Y.userName||""})}return H.map(Y=>{let D=Y.hub.id;return ee({...Y,labels:oe.get(D)||[],comments:ce.get(D)||[]},b)})},forceRefresh:d,snapshot:u,ttlMsOverride:f??x,epochKey:`${w}${R}`})},ue=async(e,n,{forceRefresh:d=!1,snapshot:u=!1,ttlMsOverride:f}={})=>{let b=`daily-report:detail:${e}:user:${n}`;return(await c.getOrFetch({cacheKey:b,fetcher:async()=>{let _=await W(t.select({hub:ne(p),internal:ne(g),isRead:E.isRead,isStarred:E.isStarred,creatorName:l.displayName,...v()}).from(p)).leftJoin(g,(0,a.eq)(p.id,g.hubId)).leftJoin(E,(0,a.and)((0,a.eq)(p.id,E.hubId),(0,a.eq)(E.userId,n))).leftJoin(l,(0,a.eq)(p.userId,l.id)).where((0,a.and)((0,a.eq)(p.id,e),(0,a.isNull)(p.deletedAt)));if(_.length===0)return[];let U=_[0].hub.id,z=await t.select({id:F.id,name:F.name,color:F.color}).from(X).innerJoin(F,(0,a.eq)(X.labelId,F.id)).where((0,a.eq)(X.hubId,U)),H=await t.select({id:k.id,body:k.body,createdAt:k.createdAt,userId:k.userId,userName:l.displayName}).from(k).leftJoin(l,(0,a.eq)(k.userId,l.id)).where((0,a.eq)(k.hubId,U)).orderBy((0,a.asc)(k.createdAt)),V=z.map(J=>({id:J.id,name:J.name,color:J.color})),re=H.map(J=>({id:J.id,content:J.body,createdAt:T(J.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:J.userId,userName:J.userName||""}));return[ee({..._[0],labels:V,comments:re},n)]},forceRefresh:d,snapshot:u,ttlMsOverride:f??x,epochKey:`${q}${e}`}))[0]??null},Ke=async(e,n,d={})=>{let u=await he(n);return u?ue(e,u,d):null},Je=async(e,n,d,u,f)=>{let b=await t.select().top(1).from(E).where((0,a.and)((0,a.eq)(E.hubId,n),(0,a.eq)(E.userId,e))),R;if(b.length>0?b[0].isStarred!==u?R=(await t.update(E).set({isStarred:u,updatedAt:new Date,updatedBy:String(e)}).output().where((0,a.and)((0,a.eq)(E.hubId,n),(0,a.eq)(E.userId,e))))[0]:R=b[0]:R=(await t.insert(E).output().values({hubId:n,userId:e,isStarred:u,isRead:!1,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}))[0],d){let _=G(d);_&&(c.invalidate(`daily-report:date:${_}:user:${e}`),await y(`${w}${_}`))}return c.invalidate(`daily-report:detail:${n}`),c.invalidate(`daily-report:detail:${n}:user:${e}`),await y(`${q}${n}`),await $(be.parse({type:"status-update",reportHubId:n,recipientRawUserId:e,statusType:"star",value:u,clientTempId:f}),"setStarStatus"),R},je=async(e,n,d,u,f)=>{let b=await t.select().top(1).from(E).where((0,a.and)((0,a.eq)(E.hubId,n),(0,a.eq)(E.userId,e))),R;if(b.length>0?b[0].isRead!==u?R=(await t.update(E).set({isRead:u,updatedAt:new Date,updatedBy:String(e)}).output().where((0,a.and)((0,a.eq)(E.hubId,n),(0,a.eq)(E.userId,e))))[0]:R=b[0]:R=(await t.insert(E).output().values({hubId:n,userId:e,isRead:u,isStarred:!1,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}))[0],d){let _=G(d);_&&(c.invalidate(`daily-report:date:${_}:user:${e}`),await y(`${w}${_}`))}return c.invalidate(`daily-report:detail:${n}`),c.invalidate(`daily-report:detail:${n}:user:${e}`),await y(`${q}${n}`),await $(be.parse({type:"status-update",reportHubId:n,recipientRawUserId:e,statusType:"read",value:u,clientTempId:f}),"setReadStatus"),R},Qe=async(e,n,d,u,f)=>{let[b]=await t.insert(k).output().values({hubId:n,userId:e,body:d,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}),[R]=await t.select({displayName:l.displayName}).top(1).from(l).where((0,a.eq)(l.id,e)),_=R?.displayName??"Unknown";if(u){let z=G(u);z&&(c.invalidatePrefix(`daily-report:date:${z}:user:`),await y(`${w}${z}`))}c.invalidate(`daily-report:detail:${n}`),c.invalidatePrefix(`daily-report:detail:${n}:user:`),await y(`${q}${n}`);let U={id:b.id,userId:h(b.userId),userName:_,content:b.body,createdAt:T(b.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await $(Ce.parse({type:"comment-add",reportHubId:n,comment:U,clientTempId:f}),"addComment"),U},We=async(e,n)=>await e.select().top(1).from(k).where((0,a.eq)(k.id,n)),Xe=async(e,n,d,u,f)=>{let b=await We(t,d);if(b.length===0)throw new Error("Not Found");if(b[0].userId!==e)throw new Error("Unauthorized");if(await t.delete(k).where((0,a.eq)(k.id,d)),u){let R=G(u);R&&(c.invalidatePrefix(`daily-report:date:${R}:user:`),await y(`${w}${R}`))}c.invalidate(`daily-report:detail:${n}`),c.invalidatePrefix(`daily-report:detail:${n}:user:`),await y(`${q}${n}`),await $(Ae.parse({type:"comment-delete",reportHubId:n,commentId:d,clientTempId:f}),"deleteComment")},Ge=async(e,n,d)=>{I.info("createDailyReport called",{userId:e,businessDate:n});let[u]=await t.select({displayName:l.displayName}).from(l).where((0,a.eq)(l.id,e)),f=u?.displayName??h(e);try{let b=await t.transaction(async U=>{I.info("Starting transaction");let z=`internal-temp-${Date.now()}-${Math.random()}`,[H]=await U.insert(p).output().values({sourceType:"Internal",sourceId:z,businessDate:new Date(n),userId:e,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)});await U.update(p).set({sourceId:String(H.id)}).where((0,a.eq)(p.id,H.id)),I.info("Hub created",H),await U.insert(g).values({hubId:H.id,body:"",createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}),I.info("Internal created"),I.info("Calling getDraftLabelId");let V=await se();I.info("draftLabelId",V);let re=[];return V&&(await U.insert(X).values({hubId:H.id,labelId:V,createdAt:new Date,createdBy:String(e)}),re.push({id:V,name:P,color:null})),I.info("Label assigned"),{reportHubId:H.id,date:n,createdAt:T(H.createdAt,"YYYY-MM-DD HH:mm:ss"),author:f,userId:h(e),sourceType:"Internal",employeeName:f,updatedBy:h(e),updatedAt:T(H.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:H.title,content:"",comments:[],isRead:!0,isStarred:!1,labels:re,commentItems:[]}}),R=G(n);R&&c.invalidate(`daily-report:date:${R}:user:${e}`),c.invalidatePrefix(B),c.invalidate(`${L}:user:${e}`),await y(S),R&&await y(`${w}${R}`);let _=await ue(b.reportHubId,e,{forceRefresh:!0});if(_){let U=await se(),z=U?_.labels.some(H=>H.id===U):!1;await $(Te.parse({type:"report-create",reportHubId:_.reportHubId,report:_,clientTempId:d,recipientRawUserId:z?e:void 0}),"createDailyReport")}return _??b}catch(b){throw I.error("Error in createDailyReport",b),b}},fe=async(e,n)=>await e.select().top(1).from(p).where((0,a.eq)(p.id,n)),we=async(e,n,d)=>{await e.update(p).set(d).where((0,a.eq)(p.id,n))},$e=async(e,n,d)=>{await e.update(g).set(d).where((0,a.eq)(g.hubId,n))},Le=async(e,n,d)=>{await e.delete(X).where((0,a.and)((0,a.eq)(X.hubId,n),(0,a.eq)(X.labelId,d)))};return{streamKey:Q,streamMaxLen:N,clearCache:async()=>{c.clearAll(),ie.clear(),de=null,j&&await y(S),I.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},getUserIdByExternalId:he,getDailyReportIdsByExternalId:Oe,getDailyReportsByBusinessDate:Fe,getDailyReportsByBusinessDateByExternalId:ze,getDailyReportDetailById:ue,getDailyReportDetailByIdByExternalId:Ke,getDraftLabelId:se,setStarStatus:Je,setReadStatus:je,addComment:Qe,deleteComment:Xe,createDailyReport:Ge,updateDailyReport:async(e,n,d,u)=>{let f=await fe(t,e);if(!f.length||f[0].deletedAt)throw new Error("Not Found");if(f[0].userId!==n)throw new Error("Unauthorized");await t.transaction(async R=>{d.title!==void 0&&await we(R,e,{title:d.title,updatedAt:new Date,updatedBy:String(n)}),d.content!==void 0&&await $e(R,e,{body:d.content,updatedAt:new Date,updatedBy:String(n)})}),c.invalidatePrefix(`daily-report:detail:${e}:user:`),c.invalidatePrefix(B);let b=await ue(e,n,{forceRefresh:!0});if(b){let R=await se(),_=R?b.labels.some(U=>U.id===R):!1;await $(ve.parse({type:"report-update",reportHubId:b.reportHubId,report:b,clientTempId:u,recipientRawUserId:_?n:void 0}),"updateDailyReport")}},publishDailyReport:async(e,n,d)=>{let u=await fe(t,e);if(!u.length)throw new Error("Not Found");if(u[0].userId!==n)throw new Error("Unauthorized");let f=await se();if(!f)return null;if(await Le(t,e,f),c.invalidatePrefix(`daily-report:detail:${e}:user:`),c.invalidatePrefix(B),c.invalidatePrefix(L),await y(S),u[0].businessDate){let _=G(T(u[0].businessDate,"YYYY-MM-DD"));_&&await y(`${w}${_}`)}let b=G(T(u[0].businessDate,"YYYY-MM-DD"));b&&c.invalidate(`daily-report:date:${b}:user:${n}`);let R=await ue(e,n,{forceRefresh:!0});return R&&await $(Me.parse({type:"report-publish",reportHubId:R.reportHubId,report:R,clientTempId:d}),"publishDailyReport"),R??null},deleteDailyReport:async(e,n,d)=>{let u=await fe(t,e);if(!u.length||u[0].deletedAt)throw new Error("Not Found");if(u[0].userId!==n)throw new Error("Unauthorized");if(await we(t,e,{deletedAt:new Date,deletedBy:String(n),updatedAt:new Date,updatedBy:String(n)}),c.invalidatePrefix(`daily-report:detail:${e}:user:`),c.invalidatePrefix(B),c.invalidatePrefix(L),await y(S),u[0].businessDate){let f=G(T(u[0].businessDate,"YYYY-MM-DD"));f&&await y(`${w}${f}`)}await $(xe.parse({type:"report-delete",reportHubId:e,clientTempId:d}),"deleteDailyReport")},findDailyReportHubById:fe,updateDailyReportHub:we,updateDailyReportInternal:$e,deleteDailyReportLabel:Le}}var ct=te(1,"[DailyReportExternalSource]"),pt=(r,t,i,l=ct)=>{if(!r)return[];try{let m=JSON.parse(r);return Array.isArray(m)?m.map(i).filter(h=>h!==null):(l.warn(`Unexpected ${t} format: not an array`),[])}catch(m){return l.warn(`Failed to parse ${t}:`,m),[]}};var ge=require("drizzle-orm"),s=require("drizzle-orm/mssql-core");function mt(r,t){let i=(0,s.mssqlSchema)(r),l=t.userTable,m=i.table("DailyReportHub",{id:(0,s.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,s.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,s.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,s.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(ge.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,s.date)("business_date"),userId:(0,s.bigint)("user_id",{mode:"number"}),title:(0,s.nvarchar)("title",{length:200}),summary:(0,s.nvarchar)("summary",{length:"max"}),createdAt:(0,s.datetime2)("created_at").notNull(),createdBy:(0,s.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,s.datetime2)("updated_at").notNull(),updatedBy:(0,s.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,s.datetime2)("deleted_at"),deletedBy:(0,s.nvarchar)("deleted_by",{length:50})},g=>[(0,s.primaryKey)({name:`${r}_DailyReportHub_pk`,columns:[g.id]}),(0,s.foreignKey)({name:`${r}_DailyReportHub_user_id_fk`,columns:[g.userId],foreignColumns:[l.id]}),(0,s.index)(`${r}_DailyReportHub_business_date_index`).on(g.businessDate),(0,s.index)(`${r}_DailyReportHub_updated_at_index`).on(g.updatedAt),(0,s.index)(`${r}_DailyReportHub_source_index`).on(g.sourceType,g.sourceId),(0,s.index)(`${r}_DailyReportHub_user_id_index`).on(g.userId),(0,s.index)(`${r}_DailyReportHub_business_date_id_index`).on((0,ge.desc)(g.businessDate),(0,ge.desc)(g.id)),(0,s.index)(`${r}_DailyReportHub_deleted_at_index`).on(g.deletedAt)]),h=i.table("DailyReportInternal",{hubId:(0,s.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,s.nvarchar)("body",{length:"max"}),metadata:(0,s.nvarchar)("metadata",{length:"max"}),createdAt:(0,s.datetime2)("created_at").notNull(),createdBy:(0,s.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,s.datetime2)("updated_at").notNull(),updatedBy:(0,s.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,s.primaryKey)({name:`${r}_DailyReportInternal_pk`,columns:[g.hubId]}),(0,s.foreignKey)({name:`${r}_DailyReportInternal_hub_id_fk`,columns:[g.hubId],foreignColumns:[m.id]})]),O=i.table("DailyReportComment",{id:(0,s.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,s.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,s.bigint)("user_id",{mode:"number"}).notNull(),body:(0,s.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,s.datetime2)("created_at").notNull(),createdBy:(0,s.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,s.datetime2)("updated_at").notNull(),updatedBy:(0,s.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,s.primaryKey)({name:`${r}_DailyReportComment_pk`,columns:[g.id]}),(0,s.foreignKey)({name:`${r}_DailyReportComment_hub_id_fk`,columns:[g.hubId],foreignColumns:[m.id]}),(0,s.foreignKey)({name:`${r}_DailyReportComment_user_id_fk`,columns:[g.userId],foreignColumns:[l.id]}),(0,s.index)(`${r}_DailyReportComment_hub_id_index`).on(g.hubId)]),c=i.table("DailyReportLabel",{id:(0,s.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,s.bigint)("user_id",{mode:"number"}),name:(0,s.nvarchar)("name",{length:50}).notNull(),color:(0,s.nvarchar)("color",{length:20}),sortOrder:(0,s.int)("sort_order"),createdAt:(0,s.datetime2)("created_at").notNull(),createdBy:(0,s.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,s.datetime2)("updated_at").notNull(),updatedBy:(0,s.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,s.primaryKey)({name:`${r}_DailyReportLabel_pk`,columns:[g.id]}),(0,s.foreignKey)({name:`${r}_DailyReportLabel_user_id_fk`,columns:[g.userId],foreignColumns:[l.id]})]),j=i.table("DailyReportHub_Label",{hubId:(0,s.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,s.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,s.datetime2)("created_at").notNull(),createdBy:(0,s.nvarchar)("created_by",{length:50}).notNull()},g=>[(0,s.primaryKey)({name:`${r}_DailyReportHub_Label_pk`,columns:[g.hubId,g.labelId]}),(0,s.foreignKey)({name:`${r}_DailyReportHub_Label_hub_id_fk`,columns:[g.hubId],foreignColumns:[m.id]}),(0,s.foreignKey)({name:`${r}_DailyReportHub_Label_label_id_fk`,columns:[g.labelId],foreignColumns:[c.id]})]),p=i.table("DailyReportUserStatus",{hubId:(0,s.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,s.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,s.bit)("is_read").default(!1).notNull(),isStarred:(0,s.bit)("is_starred").default(!1).notNull(),createdAt:(0,s.datetime2)("created_at").notNull(),createdBy:(0,s.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,s.datetime2)("updated_at").notNull(),updatedBy:(0,s.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,s.primaryKey)({name:`${r}_DailyReportUserStatus_pk`,columns:[g.hubId,g.userId]}),(0,s.foreignKey)({name:`${r}_DailyReportUserStatus_hub_id_fk`,columns:[g.hubId],foreignColumns:[m.id]}),(0,s.foreignKey)({name:`${r}_DailyReportUserStatus_user_id_fk`,columns:[g.userId],foreignColumns:[l.id]})]);return{hub:m,internal:h,comment:O,label:c,hubLabel:j,userStatus:p}}function yt(r){let t=Ie(r.redis),i=new pe({defaultTtlMs:r.cacheDefaultTtlMs??6e4},t),l=Ee({...r,cache:i,epochs:t}),m=new me({redis:r.redis,streamKey:l.streamKey,cache:i,logger:r.logger}),h=Ne({authenticate:r.authenticate,service:l,encodeUserId:r.encodeUserId,redis:r.redis,sseReader:m,streamKey:l.streamKey,loginRedirectPath:r.loginRedirectPath,logger:r.logger});return{service:l,cache:i,epochs:t,sseReader:m,streamKey:l.streamKey,...h}}0&&(module.exports={DailyReportSseReader,SqlResultCache,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportSchema,generateETag,isStreamIdLte,jsonResponseWithETag,transformJsonArray});
|
|
8
|
+
`,Q=L!=="0-0"?`id: ${L}
|
|
9
|
+
${T}`:T;M.enqueue(H.encode(Q))}if(A)try{let T=await c?.getClient();if(T){let Q=await T.xRange(q,A,"+",{COUNT:1e3});for(let te of Q)te.id!==A&&(ye(te.id,L)||(L=te.id,R(te.id,te.message)))}}catch(T){u.error(`[SSE:${S}] catch-up xRange error:`,T)}},cancel(){N()}});return new Response(C,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}}}}var a=require("drizzle-orm");var le=r=>(0,a.getColumns)(r);function $e(r){let{db:e,tables:s,userTable:i,resolveUserId:c,encodeUserId:y,redis:q,cache:p,epochs:z}=r,{hub:u,internal:g,comment:$,label:W,hubLabel:X,userStatus:k}=s,_=r.externalSources??[],U=r.draftLabelNames&&r.draftLabelNames.length>0?r.draftLabelNames:[r.draftLabelName??"\u4E0B\u66F8\u304D"],B=U[0]??"\u4E0B\u66F8\u304D",S=r.logger??re(1,"[DailyReportService]"),w="daily-report:ids",A=r.idsTtlMs??18e4,H="daily-report:ids:epoch",M="daily-report:business-date:",I=r.businessDateTtlMs??3e5,Y="daily-report:date-epoch:",F="daily-report:detail-epoch:",N=r.streamKey??"daily-report:sse-stream",R=r.streamMaxLen??1e4,C=t=>z.incrementEpoch(t),E=async(t,n)=>{let d=await q?.getClient();if(!d){S.warn(`[SSE] Redis client unavailable (${n})`);return}let m=Date.now();try{await d.xAdd(N,"*",{data:JSON.stringify(t)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:R}});let h=Date.now()-m;h>1e3&&S.warn(`[SSE] Slow publish (${n}): ${h}ms`)}catch(h){S.error(`[SSE] Redis publish failed (${n}):`,h)}},L=(t,n)=>{if(!t)return null;let d=t instanceof Date?t:new Date(t);if(Number.isNaN(d.getTime()))return typeof t=="string"?t:null;let m=n==="YYYY-MM-DD HH:mm:ss"?{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}:{year:"numeric",month:"2-digit",day:"2-digit"};return(n==="YYYY-MM-DD HH:mm:ss"?d.toLocaleString("ja-JP",m):d.toLocaleDateString("ja-JP",m)).replace(/\//g,"-")},T=t=>t==null||t===""?null:/^\d+$/.test(t)?y(Number(t)):t,Q=()=>{let t={};for(let n of _)t[`ext_${n.sourceType}`]=le(n.table);return t},te=t=>{let n=t;for(let d of _)n=n.leftJoin(d.table,(0,a.and)((0,a.eq)(u.sourceType,d.sourceType),(0,a.eq)(u.sourceIdNum,d.idColumn)));return n},ae=(t,n)=>{let{hub:d,internal:m}=t,h=d.summary,b=[],f=null,D=null,K=null,J=null,P=null,Z=null,ne=[],j=_.find(v=>v.sourceType===d.sourceType),de=j?t[`ext_${j.sourceType}`]:void 0;if(j&&de){let v=j.mapRow(de);v.content!==void 0&&(h=v.content),v.employeeName!==void 0&&(Z=v.employeeName),v.category!==void 0&&(f=v.category),v.creationCategory!==void 0&&(D=v.creationCategory),v.visitTimeFrom!==void 0&&(K=v.visitTimeFrom),v.visitTimeTo!==void 0&&(J=v.visitTimeTo),v.customerName!==void 0&&(P=v.customerName),v.interviewers!==void 0&&(b=v.interviewers),v.comments!==void 0&&(ne=v.comments)}else d.sourceType==="Internal"&&m&&(h=m.body);let ie=(t.labels??[]).map(v=>({id:v.id,name:v.name,color:v.color})),O=t.comments??[];return D&&U.includes(D)&&se&&!ie.some(v=>v.id===se)&&ie.push({id:se,name:B,color:null}),{reportHubId:d.id,date:L(d.businessDate,"YYYY-MM-DD"),author:t.creatorName??T(d.createdBy)??"",userId:d.userId?y(d.userId):"",sourceType:d.sourceType??"Internal",createdAt:L(d.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:L(d.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:T(d.updatedBy),employeeName:Z??t.creatorName??T(d.createdBy),category:f,creationCategory:D,visitTimeFrom:K,visitTimeTo:J,customerName:P,interviewers:b,subject:d.title,content:h,comments:ne,isRead:t.isRead??!1,isStarred:t.isStarred??!1,labels:ie,commentItems:O.map(v=>({...v,userId:y(v.userId),isMine:n?v.userId===n:!1}))}},ue=async t=>{let n=(0,a.aliasedTable)(X,"draft_label"),d=await oe();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).from(u).leftJoin(n,(0,a.and)((0,a.eq)(n.hubId,u.id),(0,a.eq)(n.labelId,d??-1))).where((0,a.and)((0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,t),(0,a.isNull)(u.userId),(0,a.isNull)(n.hubId)))).orderBy((0,a.desc)(u.businessDate),(0,a.desc)(u.id))).map(h=>({...h,businessDate:L(h.businessDate,"YYYY-MM-DD")}))},Pe=async t=>(await te(e.select({hub:le(u),internal:le(g),creatorName:i.displayName,...Q()}).from(u)).leftJoin(g,(0,a.eq)(u.id,g.hubId)).leftJoin(i,(0,a.eq)(u.userId,i.id)).where((0,a.and)((0,a.eq)(u.businessDate,a.sql`${t}`),(0,a.isNull)(u.deletedAt))).orderBy((0,a.desc)(u.id))).map(d=>ae(d)),Ie=t=>`${M}${t}`,fe=new Map,be=async t=>{if(!r.disableUserIdCache&&fe.has(t))return fe.get(t)??null;let n=await c(t);return n!==null&&!r.disableUserIdCache&&fe.set(t,n),n},Je=async(t,{forceRefresh:n=!1,snapshot:d=!1,ttlMsOverride:m}={})=>{let h=await be(t);if(!h)return[];let b=`${w}:user:${h}`;return p.getOrFetch({cacheKey:b,fetcher:async()=>await ue(h),forceRefresh:n,snapshot:d,ttlMsOverride:m??A,epochKey:H})},je=(t,{forceRefresh:n=!1,snapshot:d=!1,ttlMsOverride:m}={})=>{let h=V(t);return h?p.getOrFetch({cacheKey:Ie(h),fetcher:()=>Pe(h),forceRefresh:n,snapshot:d,ttlMsOverride:m??I}):Promise.resolve([])},se=null,oe=async()=>{if(se!==null)return se;let[t]=await e.select({id:W.id}).top(1).from(W).where((0,a.inArray)(W.name,U));return t?(se=t.id,se):null},Qe=async(t,n,{forceRefresh:d=!1,snapshot:m=!1,ttlMsOverride:h}={})=>{let b=await be(n);if(!b)return[];let f=V(t);if(!f)return[];let D=`daily-report:date:${f}:user:${b}`;return p.getOrFetch({cacheKey:D,fetcher:async()=>{let K=await oe(),J=(0,a.aliasedTable)(X,"draft_label"),P=await te(e.select({hub:le(u),internal:le(g),isRead:k.isRead,isStarred:k.isStarred,creatorName:i.displayName,...Q()}).from(u)).leftJoin(g,(0,a.eq)(u.id,g.hubId)).leftJoin(k,(0,a.and)((0,a.eq)(u.id,k.hubId),(0,a.eq)(k.userId,b))).leftJoin(J,(0,a.and)((0,a.eq)(J.hubId,u.id),(0,a.eq)(J.labelId,K??-1))).leftJoin(i,(0,a.eq)(u.userId,i.id)).where((0,a.and)((0,a.eq)(u.businessDate,a.sql`${f}`),(0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,b),(0,a.isNull)(J.hubId)))).orderBy((0,a.desc)(u.id));if(P.length===0)return[];let Z=P.map(O=>O.hub.id),ne=await e.select({hubId:X.hubId,id:W.id,name:W.name,color:W.color}).from(X).innerJoin(W,(0,a.eq)(X.labelId,W.id)).where((0,a.inArray)(X.hubId,Z)),j=await e.select({hubId:$.hubId,id:$.id,body:$.body,createdAt:$.createdAt,userId:$.userId,userName:i.displayName}).from($).leftJoin(i,(0,a.eq)($.userId,i.id)).where((0,a.inArray)($.hubId,Z)).orderBy((0,a.asc)($.createdAt)),de=new Map,ie=new Map;for(let O of ne){let G=de.get(O.hubId);G||(G=[],de.set(O.hubId,G)),G.push({id:O.id,name:O.name,color:O.color})}for(let O of j){let G=ie.get(O.hubId);G||(G=[],ie.set(O.hubId,G)),G.push({id:O.id,content:O.body,createdAt:L(O.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:O.userId,userName:O.userName||""})}return P.map(O=>{let G=O.hub.id;return ae({...O,labels:de.get(G)||[],comments:ie.get(G)||[]},b)})},forceRefresh:d,snapshot:m,ttlMsOverride:h??I,epochKey:`${Y}${f}`})},ce=async(t,n,{forceRefresh:d=!1,snapshot:m=!1,ttlMsOverride:h}={})=>{let b=`daily-report:detail:${t}:user:${n}`;return(await p.getOrFetch({cacheKey:b,fetcher:async()=>{let D=await te(e.select({hub:le(u),internal:le(g),isRead:k.isRead,isStarred:k.isStarred,creatorName:i.displayName,...Q()}).from(u)).leftJoin(g,(0,a.eq)(u.id,g.hubId)).leftJoin(k,(0,a.and)((0,a.eq)(u.id,k.hubId),(0,a.eq)(k.userId,n))).leftJoin(i,(0,a.eq)(u.userId,i.id)).where((0,a.and)((0,a.eq)(u.id,t),(0,a.isNull)(u.deletedAt)));if(D.length===0)return[];let K=D[0].hub.id,J=await e.select({id:W.id,name:W.name,color:W.color}).from(X).innerJoin(W,(0,a.eq)(X.labelId,W.id)).where((0,a.eq)(X.hubId,K)),P=await e.select({id:$.id,body:$.body,createdAt:$.createdAt,userId:$.userId,userName:i.displayName}).from($).leftJoin(i,(0,a.eq)($.userId,i.id)).where((0,a.eq)($.hubId,K)).orderBy((0,a.asc)($.createdAt)),Z=J.map(j=>({id:j.id,name:j.name,color:j.color})),ne=P.map(j=>({id:j.id,content:j.body,createdAt:L(j.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:j.userId,userName:j.userName||""}));return[ae({...D[0],labels:Z,comments:ne},n)]},forceRefresh:d,snapshot:m,ttlMsOverride:h??I,epochKey:`${F}${t}`}))[0]??null},We=async(t,n,d={})=>{let m=await be(n);return m?ce(t,m,d):null},Xe=async(t,n,d,m,h)=>{let b=await e.select().top(1).from(k).where((0,a.and)((0,a.eq)(k.hubId,n),(0,a.eq)(k.userId,t))),f;if(b.length>0?b[0].isStarred!==m?f=(await e.update(k).set({isStarred:m,updatedAt:new Date,updatedBy:String(t)}).output().where((0,a.and)((0,a.eq)(k.hubId,n),(0,a.eq)(k.userId,t))))[0]:f=b[0]:f=(await e.insert(k).output().values({hubId:n,userId:t,isStarred:m,isRead:!1,createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}))[0],d){let D=V(d);D&&(p.invalidate(`daily-report:date:${D}:user:${t}`),await C(`${Y}${D}`))}return p.invalidate(`daily-report:detail:${n}`),p.invalidate(`daily-report:detail:${n}:user:${t}`),await C(`${F}${n}`),await E(De.parse({type:"status-update",reportHubId:n,recipientRawUserId:t,statusType:"star",value:m,clientTempId:h}),"setStarStatus"),f},Ge=async(t,n,d,m,h)=>{let b=await e.select().top(1).from(k).where((0,a.and)((0,a.eq)(k.hubId,n),(0,a.eq)(k.userId,t))),f;if(b.length>0?b[0].isRead!==m?f=(await e.update(k).set({isRead:m,updatedAt:new Date,updatedBy:String(t)}).output().where((0,a.and)((0,a.eq)(k.hubId,n),(0,a.eq)(k.userId,t))))[0]:f=b[0]:f=(await e.insert(k).output().values({hubId:n,userId:t,isRead:m,isStarred:!1,createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}))[0],d){let D=V(d);D&&(p.invalidate(`daily-report:date:${D}:user:${t}`),await C(`${Y}${D}`))}return p.invalidate(`daily-report:detail:${n}`),p.invalidate(`daily-report:detail:${n}:user:${t}`),await C(`${F}${n}`),await E(De.parse({type:"status-update",reportHubId:n,recipientRawUserId:t,statusType:"read",value:m,clientTempId:h}),"setReadStatus"),f},Ve=async(t,n,d,m,h)=>{let[b]=await e.select({sourceType:u.sourceType}).top(1).from(u).where((0,a.eq)(u.id,n));if(b&&b.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let[f]=await e.insert($).output().values({hubId:n,userId:t,body:d,createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}),[D]=await e.select({displayName:i.displayName}).top(1).from(i).where((0,a.eq)(i.id,t)),K=D?.displayName??"Unknown";if(m){let P=V(m);P&&(p.invalidatePrefix(`daily-report:date:${P}:user:`),await C(`${Y}${P}`))}p.invalidate(`daily-report:detail:${n}`),p.invalidatePrefix(`daily-report:detail:${n}:user:`),await C(`${F}${n}`);let J={id:f.id,userId:y(f.userId),userName:K,content:f.body,createdAt:L(f.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await E(ve.parse({type:"comment-add",reportHubId:n,comment:J,clientTempId:h}),"addComment"),J},Ze=async(t,n)=>await t.select().top(1).from($).where((0,a.eq)($.id,n)),et=async(t,n,d,m,h)=>{let b=await Ze(e,d);if(b.length===0)throw new Error("Not Found");if(b[0].userId!==t)throw new Error("Unauthorized");if(await e.delete($).where((0,a.eq)($.id,d)),m){let f=V(m);f&&(p.invalidatePrefix(`daily-report:date:${f}:user:`),await C(`${Y}${f}`))}p.invalidate(`daily-report:detail:${n}`),p.invalidatePrefix(`daily-report:detail:${n}:user:`),await C(`${F}${n}`),await E(Me.parse({type:"comment-delete",reportHubId:n,commentId:d,clientTempId:h}),"deleteComment")},tt=async(t,n,d)=>{S.info("createDailyReport called",{userId:t,businessDate:n});let[m]=await e.select({displayName:i.displayName}).from(i).where((0,a.eq)(i.id,t)),h=m?.displayName??y(t);try{let b=await e.transaction(async K=>{S.info("Starting transaction");let J=`internal-temp-${Date.now()}-${Math.random()}`,[P]=await K.insert(u).output().values({sourceType:"Internal",sourceId:J,businessDate:new Date(n),userId:t,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)});await K.update(u).set({sourceId:String(P.id)}).where((0,a.eq)(u.id,P.id)),S.info("Hub created",P),await K.insert(g).values({hubId:P.id,body:"",createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}),S.info("Internal created"),S.info("Calling getDraftLabelId");let Z=await oe();S.info("draftLabelId",Z);let ne=[];return Z&&(await K.insert(X).values({hubId:P.id,labelId:Z,createdAt:new Date,createdBy:String(t)}),ne.push({id:Z,name:B,color:null})),S.info("Label assigned"),{reportHubId:P.id,date:n,createdAt:L(P.createdAt,"YYYY-MM-DD HH:mm:ss"),author:h,userId:y(t),sourceType:"Internal",employeeName:h,updatedBy:y(t),updatedAt:L(P.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:P.title,content:"",comments:[],isRead:!0,isStarred:!1,labels:ne,commentItems:[]}}),f=V(n);f&&p.invalidate(`daily-report:date:${f}:user:${t}`),p.invalidatePrefix(M),p.invalidate(`${w}:user:${t}`),await C(H),f&&await C(`${Y}${f}`);let D=await ce(b.reportHubId,t,{forceRefresh:!0});if(D){let K=await oe(),J=K?D.labels.some(P=>P.id===K):!1;await E(xe.parse({type:"report-create",reportHubId:D.reportHubId,report:D,clientTempId:d,recipientRawUserId:J?t:void 0}),"createDailyReport")}return D??b}catch(b){throw S.error("Error in createDailyReport",b),b}},Re=async(t,n)=>await t.select().top(1).from(u).where((0,a.eq)(u.id,n)),Ce=async(t,n,d)=>{await t.update(u).set(d).where((0,a.eq)(u.id,n))},Be=async(t,n,d)=>{await t.update(g).set(d).where((0,a.eq)(g.hubId,n))},Ue=async(t,n,d)=>{await t.delete(X).where((0,a.and)((0,a.eq)(X.hubId,n),(0,a.eq)(X.labelId,d)))};return{streamKey:N,streamMaxLen:R,clearCache:async()=>{p.clearAll(),fe.clear(),se=null,z&&await C(H),S.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},getUserIdByExternalId:be,getDailyReportIdsByExternalId:Je,getDailyReportsByBusinessDate:je,getDailyReportsByBusinessDateByExternalId:Qe,getDailyReportDetailById:ce,getDailyReportDetailByIdByExternalId:We,getDraftLabelId:oe,setStarStatus:Xe,setReadStatus:Ge,addComment:Ve,deleteComment:et,createDailyReport:tt,updateDailyReport:async(t,n,d,m)=>{let h=await Re(e,t);if(!h.length||h[0].deletedAt)throw new Error("Not Found");if(h[0].userId!==n)throw new Error("Unauthorized");await e.transaction(async f=>{d.title!==void 0&&await Ce(f,t,{title:d.title,updatedAt:new Date,updatedBy:String(n)}),d.content!==void 0&&await Be(f,t,{body:d.content,updatedAt:new Date,updatedBy:String(n)})}),p.invalidatePrefix(`daily-report:detail:${t}:user:`),p.invalidatePrefix(M);let b=await ce(t,n,{forceRefresh:!0});if(b){let f=await oe(),D=f?b.labels.some(K=>K.id===f):!1;await E(Ne.parse({type:"report-update",reportHubId:b.reportHubId,report:b,clientTempId:m,recipientRawUserId:D?n:void 0}),"updateDailyReport")}},publishDailyReport:async(t,n,d)=>{let m=await Re(e,t);if(!m.length)throw new Error("Not Found");if(m[0].userId!==n)throw new Error("Unauthorized");let h=await oe();if(!h)return null;if(await Ue(e,t,h),p.invalidatePrefix(`daily-report:detail:${t}:user:`),p.invalidatePrefix(M),p.invalidatePrefix(w),await C(H),m[0].businessDate){let D=V(L(m[0].businessDate,"YYYY-MM-DD"));D&&await C(`${Y}${D}`)}let b=V(L(m[0].businessDate,"YYYY-MM-DD"));b&&p.invalidate(`daily-report:date:${b}:user:${n}`);let f=await ce(t,n,{forceRefresh:!0});return f&&await E(Ee.parse({type:"report-publish",reportHubId:f.reportHubId,report:f,clientTempId:d}),"publishDailyReport"),f??null},deleteDailyReport:async(t,n,d)=>{let m=await Re(e,t);if(!m.length||m[0].deletedAt)throw new Error("Not Found");if(m[0].userId!==n)throw new Error("Unauthorized");if(await Ce(e,t,{deletedAt:new Date,deletedBy:String(n),updatedAt:new Date,updatedBy:String(n)}),p.invalidatePrefix(`daily-report:detail:${t}:user:`),p.invalidatePrefix(M),p.invalidatePrefix(w),await C(H),m[0].businessDate){let h=V(L(m[0].businessDate,"YYYY-MM-DD"));h&&await C(`${Y}${h}`)}await E(ke.parse({type:"report-delete",reportHubId:t,clientTempId:d}),"deleteDailyReport")},findDailyReportHubById:Re,updateDailyReportHub:Ce,updateDailyReportInternal:Be,deleteDailyReportLabel:Ue}}var ge=require("drizzle-orm");function ze(r){let e=[],s=r&&r.length>0?r:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let i of s){let y=`daily_report_${i.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:y,name:i.name,description:i.description??`${i.name} daily report access`}),i.includeCommentResource!==!1&&e.push({resourceKey:`${y}_comment`,name:`${i.name} Comment`,description:`${i.name} daily report comment access`})}return e}async function gt(r,e,s){let i=r,c=e.TMResource,y=s.appKey,q=s.actor??"system:daily-report",p=new Date,z=s.resources??ze(s.sources);for(let u of z){let g=await i.select().from(c).where((0,ge.and)((0,ge.eq)(c.appKey,y),(0,ge.eq)(c.resourceKey,u.resourceKey)));(!g||g.length===0)&&await i.insert(c).values({appKey:y,resourceKey:u.resourceKey,name:u.name,description:u.description??null,createdAt:p,createdBy:q,updatedAt:p,updatedBy:q})}}var ht=re(1,"[DailyReportExternalSource]"),ft=(r,e,s,i=ht)=>{if(!r)return[];try{let c=JSON.parse(r);return Array.isArray(c)?c.map(s).filter(y=>y!==null):(i.warn(`Unexpected ${e} format: not an array`),[])}catch(c){return i.warn(`Failed to parse ${e}:`,c),[]}};var he=require("drizzle-orm"),o=require("drizzle-orm/mssql-core");function bt(r,e){let s=(0,o.mssqlSchema)(r),i=e.userTable,c=s.table("DailyReportHub",{id:(0,o.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,o.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,o.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,o.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(he.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,o.date)("business_date"),userId:(0,o.bigint)("user_id",{mode:"number"}),title:(0,o.nvarchar)("title",{length:200}),summary:(0,o.nvarchar)("summary",{length:"max"}),createdAt:(0,o.datetime2)("created_at").notNull(),createdBy:(0,o.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,o.datetime2)("updated_at").notNull(),updatedBy:(0,o.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,o.datetime2)("deleted_at"),deletedBy:(0,o.nvarchar)("deleted_by",{length:50})},g=>[(0,o.primaryKey)({name:`${r}_DailyReportHub_pk`,columns:[g.id]}),(0,o.foreignKey)({name:`${r}_DailyReportHub_user_id_fk`,columns:[g.userId],foreignColumns:[i.id]}),(0,o.index)(`${r}_DailyReportHub_business_date_index`).on(g.businessDate),(0,o.index)(`${r}_DailyReportHub_updated_at_index`).on(g.updatedAt),(0,o.index)(`${r}_DailyReportHub_source_index`).on(g.sourceType,g.sourceId),(0,o.index)(`${r}_DailyReportHub_user_id_index`).on(g.userId),(0,o.index)(`${r}_DailyReportHub_business_date_id_index`).on((0,he.desc)(g.businessDate),(0,he.desc)(g.id)),(0,o.index)(`${r}_DailyReportHub_deleted_at_index`).on(g.deletedAt)]),y=s.table("DailyReportInternal",{hubId:(0,o.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,o.nvarchar)("body",{length:"max"}),metadata:(0,o.nvarchar)("metadata",{length:"max"}),createdAt:(0,o.datetime2)("created_at").notNull(),createdBy:(0,o.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,o.datetime2)("updated_at").notNull(),updatedBy:(0,o.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,o.primaryKey)({name:`${r}_DailyReportInternal_pk`,columns:[g.hubId]}),(0,o.foreignKey)({name:`${r}_DailyReportInternal_hub_id_fk`,columns:[g.hubId],foreignColumns:[c.id]})]),q=s.table("DailyReportComment",{id:(0,o.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,o.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,o.bigint)("user_id",{mode:"number"}).notNull(),body:(0,o.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,o.datetime2)("created_at").notNull(),createdBy:(0,o.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,o.datetime2)("updated_at").notNull(),updatedBy:(0,o.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,o.primaryKey)({name:`${r}_DailyReportComment_pk`,columns:[g.id]}),(0,o.foreignKey)({name:`${r}_DailyReportComment_hub_id_fk`,columns:[g.hubId],foreignColumns:[c.id]}),(0,o.foreignKey)({name:`${r}_DailyReportComment_user_id_fk`,columns:[g.userId],foreignColumns:[i.id]}),(0,o.index)(`${r}_DailyReportComment_hub_id_index`).on(g.hubId)]),p=s.table("DailyReportLabel",{id:(0,o.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,o.bigint)("user_id",{mode:"number"}),name:(0,o.nvarchar)("name",{length:50}).notNull(),color:(0,o.nvarchar)("color",{length:20}),sortOrder:(0,o.int)("sort_order"),createdAt:(0,o.datetime2)("created_at").notNull(),createdBy:(0,o.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,o.datetime2)("updated_at").notNull(),updatedBy:(0,o.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,o.primaryKey)({name:`${r}_DailyReportLabel_pk`,columns:[g.id]}),(0,o.foreignKey)({name:`${r}_DailyReportLabel_user_id_fk`,columns:[g.userId],foreignColumns:[i.id]})]),z=s.table("DailyReportHub_Label",{hubId:(0,o.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,o.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,o.datetime2)("created_at").notNull(),createdBy:(0,o.nvarchar)("created_by",{length:50}).notNull()},g=>[(0,o.primaryKey)({name:`${r}_DailyReportHub_Label_pk`,columns:[g.hubId,g.labelId]}),(0,o.foreignKey)({name:`${r}_DailyReportHub_Label_hub_id_fk`,columns:[g.hubId],foreignColumns:[c.id]}),(0,o.foreignKey)({name:`${r}_DailyReportHub_Label_label_id_fk`,columns:[g.labelId],foreignColumns:[p.id]})]),u=s.table("DailyReportUserStatus",{hubId:(0,o.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,o.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,o.bit)("is_read").default(!1).notNull(),isStarred:(0,o.bit)("is_starred").default(!1).notNull(),createdAt:(0,o.datetime2)("created_at").notNull(),createdBy:(0,o.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,o.datetime2)("updated_at").notNull(),updatedBy:(0,o.nvarchar)("updated_by",{length:50}).notNull()},g=>[(0,o.primaryKey)({name:`${r}_DailyReportUserStatus_pk`,columns:[g.hubId,g.userId]}),(0,o.foreignKey)({name:`${r}_DailyReportUserStatus_hub_id_fk`,columns:[g.hubId],foreignColumns:[c.id]}),(0,o.foreignKey)({name:`${r}_DailyReportUserStatus_user_id_fk`,columns:[g.userId],foreignColumns:[i.id]})]);return{hub:c,internal:y,comment:q,label:p,hubLabel:z,userStatus:u}}function Rt(r){let e=Ae(r.redis),s=new pe({defaultTtlMs:r.cacheDefaultTtlMs??6e4},e),i=$e({...r,cache:s,epochs:e}),c=new me({redis:r.redis,streamKey:i.streamKey,cache:s,logger:r.logger}),y=Le({authenticate:r.authenticate,service:i,encodeUserId:r.encodeUserId,redis:r.redis,sseReader:c,streamKey:i.streamKey,loginRedirectPath:r.loginRedirectPath,logger:r.logger});return{service:i,cache:s,epochs:e,sseReader:c,streamKey:i.streamKey,...y}}0&&(module.exports={DailyReportSseReader,SqlResultCache,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,generateETag,isStreamIdLte,jsonResponseWithETag,seedDailyReportAuthzResources,transformJsonArray});
|
|
10
10
|
//# sourceMappingURL=server.js.map
|