@aiquants/daily-report 0.6.2 → 0.7.0
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/dist/client.d.mts +81 -3
- package/dist/client.d.ts +81 -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/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +434 -6
- package/dist/server.d.ts +434 -6
- 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/dist/{sse-schema-rbG114od.d.mts → sse-schema-Df49KA7B.d.mts} +643 -249
- package/dist/{sse-schema-eXcMG-Ej.d.ts → sse-schema-RHckD7TS.d.ts} +643 -249
- package/dist/styles/daily-report.standalone.css +1 -1
- package/dist/{types-D1PKubyo.d.mts → types-Ct1ggzy-.d.mts} +30 -1
- package/dist/{types-D1PKubyo.d.ts → types-Ct1ggzy-.d.ts} +30 -1
- package/package.json +3 -3
- package/src/client/components/daily-report-attachment-indicator.spec.tsx +51 -0
- package/src/client/components/daily-report-attachment-indicator.tsx +45 -0
- package/src/client/components/daily-report-attachment-list.spec.tsx +94 -0
- package/src/client/components/daily-report-attachment-list.tsx +112 -0
- package/src/client/components/daily-report-detail-list.tsx +14 -7
- package/src/client/components/daily-report-list.tsx +19 -11
- package/src/client/components/report-views.spec.tsx +340 -0
- package/src/client/config-context.tsx +8 -0
- package/src/client/contexts/daily-report-action-context.tsx +2 -0
- package/src/client/hooks/use-responsive-layout.spec.ts +74 -0
- package/src/client/hooks/use-responsive-layout.ts +56 -0
- package/src/client/utils/constants.spec.ts +96 -0
- package/src/client/utils/constants.ts +47 -2
- package/src/client.ts +2 -0
- package/src/server/handlers.attachment.spec.ts +470 -0
- package/src/server/handlers.ts +426 -1
- package/src/server/ports.ts +74 -0
- package/src/server/schema.ts +80 -5
- package/src/server/service.spec.ts +280 -14
- package/src/server/service.ts +308 -25
- package/src/server/test-helpers/handlers-config.ts +142 -0
- package/src/server.ts +16 -1
- package/src/shared/sse-schema.spec.ts +50 -0
- package/src/shared/sse-schema.ts +27 -0
- package/src/shared/types.ts +31 -0
package/dist/server.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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: ${
|
|
1
|
+
"use strict";var Ne=Object.defineProperty;var pt=Object.getOwnPropertyDescriptor;var yt=Object.getOwnPropertyNames;var ht=Object.prototype.hasOwnProperty;var ft=(r,e)=>{for(var o in e)Ne(r,o,{get:e[o],enumerable:!0})},gt=(r,e,o,l)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of yt(e))!ht.call(r,p)&&p!==o&&Ne(r,p,{get:()=>e[p],enumerable:!(l=pt(e,p))||l.enumerable});return r};var bt=r=>gt(Ne({},"__esModule",{value:!0}),r);var Jt={};ft(Jt,{DailyReportSseReader:()=>De,SqlResultCache:()=>Re,asciiFallbackFileName:()=>Ze,createDailyReportHandlers:()=>Oe,createDailyReportServer:()=>jt,createDailyReportService:()=>ze,createEpochStore:()=>xe,defineDailyReportAuthzResources:()=>et,defineDailyReportSchema:()=>Kt,encodeRfc8187:()=>Ve,generateETag:()=>ke,isStreamIdLte:()=>we,jsonResponseWithETag:()=>ne,sanitizeMediaType:()=>Ye,seedDailyReportAuthzResources:()=>Ot,transformJsonArray:()=>Ft});module.exports=bt(Jt);var xe=r=>({async getEpoch(e){try{let o=await r?.getClient();if(!o)return 0;let l=await o.get(e);return l?Number(l):0}catch{return 0}},async incrementEpoch(e){try{let o=await r?.getClient();if(!o)return;await o.incr(e)}catch{}}}),Re=class{constructor(e,o){this.config=e;this.epochStore=o;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:o,forceRefresh:l,snapshot:p}=e,y=this.buckets.get(o);if(l&&(this.buckets.delete(o),this.inFlight.delete(o)),!l&&y&&y.expireAt>Date.now())if(e.epochKey){let h=await this.epochStore.getEpoch(e.epochKey);if(y.epoch===h)return p?y.records.map(O=>structuredClone(O)):y.records;this.buckets.delete(o)}else return p?y.records.map(h=>structuredClone(h)):y.records;if(!l&&this.inFlight.has(o)){let h=await this.inFlight.get(o);return p?h.map(O=>structuredClone(O)):h}let L;L=(async()=>{let h=await e.fetcher();if(l||this.inFlight.get(o)===L){let O=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs),c=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0;this.buckets.set(o,{records:h,expireAt:O,epoch:c}),this.buckets.size>500&&this.cleanExpired()}return h})(),l||this.inFlight.set(o,L);try{let h=await L;return p?h.map(O=>structuredClone(O)):h}finally{this.inFlight.delete(o)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let o of this.buckets.keys())o.startsWith(e)&&this.buckets.delete(o);for(let o of this.inFlight.keys())o.startsWith(e)&&this.inFlight.delete(o)}}cleanExpired(){let e=Date.now();for(let[o,l]of this.buckets.entries())l.expireAt<=e&&this.buckets.delete(o)}};var Rt=/^\d{4}-\d{2}-\d{2}$/,Dt=/^\d{4}\/\d{2}\/\d{2}$/,je=r=>r<10?`0${r}`:`${r}`,Je=r=>{if(Number.isNaN(r.getTime()))return null;let e=r.getFullYear(),o=je(r.getMonth()+1),l=je(r.getDate());return`${e}-${o}-${l}`},ee=r=>{if(r==null)return null;if(r instanceof Date)return Je(r);let e=r.trim();if(e==="")return null;if(Rt.test(e))return e;if(Dt.test(e))return e.replaceAll("/","-");let o=new Date(e);return Je(o)};var re=(r,e,o=console)=>{let l=p=>typeof p=="string"?[`${e} ${p}`]:[e,p];return{debug:(p,...y)=>{r<=0&&o.debug(...l(p),...y)},info:(p,...y)=>{r<=1&&o.info(...l(p),...y)},warn:(p,...y)=>{r<=2&&o.warn(...l(p),...y)},error:(p,...y)=>{r<=3&&o.error(...l(p),...y)}}};var d=require("zod"),wt=d.z.object({name:d.z.string().nullish(),affiliation:d.z.string().nullish()}),St=d.z.object({name:d.z.string().nullish(),text:d.z.string().nullish(),color:d.z.string().nullish()}),It=d.z.object({id:d.z.number(),name:d.z.string().nullish(),color:d.z.string().nullish()}),Qe=d.z.object({id:d.z.number(),userId:d.z.string().nullish(),userName:d.z.string().nullish(),content:d.z.string().nullish(),createdAt:d.z.string().nullish(),isMine:d.z.boolean()}),At=d.z.object({id:d.z.string(),fileName:d.z.string(),fileType:d.z.string().nullable(),fileSize:d.z.number().nullable(),createdAt:d.z.string().nullable(),state:d.z.enum(["present","absent","unknown"])}),Le=d.z.object({reportHubId:d.z.number(),date:d.z.string().nullish(),createdAt:d.z.string().nullish(),author:d.z.string().nullish(),userId:d.z.string().nullish(),sourceType:d.z.string().nullish(),employeeName:d.z.string().nullish(),updatedBy:d.z.string().nullish(),updatedAt:d.z.string().nullish(),category:d.z.string().nullish(),creationCategory:d.z.string().nullish(),visitTimeFrom:d.z.string().nullish(),visitTimeTo:d.z.string().nullish(),customerName:d.z.string().nullish(),interviewers:d.z.array(wt),subject:d.z.string().nullish(),content:d.z.string().nullish(),comments:d.z.array(St),isRead:d.z.boolean(),isStarred:d.z.boolean(),labels:d.z.array(It),commentItems:d.z.array(Qe),attachments:d.z.array(At).default([])}),_t=d.z.object({type:d.z.literal("connected")}),Me=d.z.object({type:d.z.literal("status-update"),reportHubId:d.z.number(),statusType:d.z.enum(["star","read"]),value:d.z.boolean(),clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),$e=d.z.object({type:d.z.literal("comment-add"),reportHubId:d.z.number(),comment:Qe,clientTempId:d.z.string()}),Pe=d.z.object({type:d.z.literal("comment-delete"),reportHubId:d.z.number(),commentId:d.z.number(),clientTempId:d.z.string()}),Be=d.z.object({type:d.z.literal("report-create"),reportHubId:d.z.number(),report:Le,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),Ue=d.z.object({type:d.z.literal("report-update"),reportHubId:d.z.number(),report:Le,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),He=d.z.object({type:d.z.literal("report-publish"),reportHubId:d.z.number(),report:Le,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),qe=d.z.object({type:d.z.literal("report-delete"),reportHubId:d.z.number(),clientTempId:d.z.string()}),Ge=d.z.discriminatedUnion("type",[_t,Me,$e,Pe,Be,Ue,He,qe]);var Xe=require("crypto"),ke=r=>{let e=JSON.stringify(r);return`"${(0,Xe.createHash)("sha256").update(e).digest("hex")}"`};var Ct=re(1,"[Response]"),ne=(r,e,o,l=200,p=Ct)=>{let y=ke(o),L=r.headers.get("If-None-Match");p.info(`[jsonResponseWithETag] ETag: ${y}, If-None-Match: ${L}`);let h=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&&h.append("Set-Cookie",e),r.method==="GET"&&l===200&&L===y?new Response(null,{status:304,headers:h}):new Response(JSON.stringify(o),{status:l,headers:h})};var We=require("events");var we=(r,e)=>{let[o,l]=r.split("-").map(Number),[p,y]=e.split("-").map(Number);return o!==p?o<p:l<=y},De=class{constructor(e){this.config=e;this._emitter=new We.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,o){return this._emitter.on("entry",e),o&&this._emitter.on("error",o),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),o&&this._emitter.removeListener("error",o),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 o of e)for(let l of o.messages){this._lastId=l.id;try{let p=l.message?.data?JSON.parse(l.message.data):null,y=p?.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 L=p?.reportHubId;typeof L=="number"&&(this.config.cache.invalidate(`daily-report:detail:${L}`),this.config.cache.invalidatePrefix(`daily-report:detail:${L}:user:`))}}catch{}this._emitter.emit("entry",{id:l.id,message:l.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"}}),Tt=32*1024*1024,Mt=60,kt=4,vt=12e4,Et=1024,Nt=60,xt=5,Lt=new Set(["image/png","image/jpeg","image/gif","image/webp","application/pdf","text/plain"]),$t=/^[\x20-\x7E]+$/,Pt=/^[\w.+-]+\/[\w.+-]+/,Ye=r=>r&&$t.test(r)&&Pt.test(r)?r:null,Ve=r=>encodeURIComponent(r).replace(/['()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`),Ze=r=>r.replace(/[^\x20-\x7E]/g,"_").replace(/["\\]/g,"_"),Bt=r=>{switch(r){case"not_found":case"denied":case"invalid_path":return 404;case"too_large":return 413;default:return 502}},Ut={404:"Attachment not found",413:"Attachment too large",502:"Attachment storage unavailable"},Ht=r=>{let e=new Map;return(o,l)=>{let p=e.get(o);p&&e.delete(o);let y=p??{tokens:r,lastRefillMs:l},L=Math.max(0,l-y.lastRefillMs);L>0&&(y.tokens=Math.min(r,y.tokens+L*r/6e4),y.lastRefillMs=l);let h=y.tokens>=1;for(h&&(y.tokens-=1),e.set(o,y);e.size>Et;){let O=e.keys().next();if(O.done)break;e.delete(O.value)}return h}},qt=r=>{let e=0;return{tryAcquire:()=>e>=r?!1:(e+=1,!0),release:()=>{e>0&&(e-=1)}}},Yt=(r,e,o)=>{let l=setTimeout(e,o);l.unref?.();let p=()=>{clearTimeout(l),e()},y=!1;return new ReadableStream({pull(L){if(y){L.close(),p();return}y=!0,L.enqueue(r)},cancel(){p()}})};function Oe(r){let{authenticate:e,service:o,encodeUserId:l,redis:p,sseReader:y,streamKey:L}=r,h=r.loginRedirectPath??"/auth/login",O=r.logger??re(3,"[DailyReportAPI]"),c=r.logger??re(1,"[DailyReportSSE]"),$=r.logger??re(1,"[DailyReportAttachment]"),m=r.attachmentMaxBytes??Tt,K=Ht(r.attachmentRateLimitPerMinute??Mt),j=qt(r.attachmentConcurrency??kt),B=async({request:M})=>{let{user:U,cookie:v}=await e(M,{failureRedirect:h}),k=new Headers;v&&k.append("Set-Cookie",v);let b=null;U&&(b=await o.getUserIdByExternalId(U.id));let S=b?l(b):null;return{data:{user:U,userId:S},headers:k}},he={"business-date":async(M,U,v,k)=>{let b=ee(M.searchParams.get("businessDate")),S=M.searchParams.get("forceRefresh")==="true";if(!b)return ne(v,U,{error:{message:"Invalid business date"}},400);let H=await o.getDailyReportsByBusinessDateByExternalId(b,k.id,{forceRefresh:S});return ne(v,U,{businessDate:b,reports:H},200)},ids:async(M,U,v,k)=>{let b=M.searchParams.get("forceRefresh")==="true",S=await o.getDailyReportIdsByExternalId(k.id,{forceRefresh:b});return ne(v,U,{ids:S},200)},report:async(M,U,v,k)=>{let b=M.searchParams.get("reportHubId"),S=M.searchParams.get("forceRefresh")==="true",H=b?Number.parseInt(b,10):NaN;if(!Number.isFinite(H)||H<=0)return ne(v,U,{error:{message:"Invalid reportHubId"}},400);let E=await o.getDailyReportDetailByIdByExternalId(H,k.id,{snapshot:!0,forceRefresh:S});return E?ne(v,U,{report:E},200):ne(v,U,{error:{message:"Report not found"}},404)}};return{index:{loader:B},api:{loader:async({request:M,params:U})=>{let{user:v,cookie:k}=await e(M,{failureRedirect:null}),b=k??null;if(!v)return ne(M,b,{error:{message:"Unauthorized"}},401);if(M.method!=="GET")return ne(M,b,{error:{message:"Method not allowed"}},405);let S=U.endpoint??"",H=he[S];if(!H)return ne(M,b,{error:{message:"Unknown endpoint"}},404);let E=Date.now();try{let R=new URL(M.url);return await H(R,b,M,v)}catch(R){let A=Date.now()-E,_=R instanceof Error?R:new Error(String(R));return O.error(`500 endpoint=${S} elapsed=${A}ms name=${_.name} code=${"code"in _?_.code:"N/A"} message=${_.message}`),O.error("Stack:",_.stack),ne(M,b,{error:{message:"Internal Server Error"}},500)}},action:async({request:M,params:U})=>{let{user:v}=await e(M,{failureRedirect:null});if(!v)return x({error:"Unauthorized"},{status:401});if(U.endpoint!=="action")return x({error:"Unknown endpoint"},{status:404});let b=await o.getUserIdByExternalId(v.id);if(!b)return x({error:"User not found"},{status:404});let S=await M.formData(),H=S.get("intent"),E=S.get("reportHubId"),R=E?Number(E):NaN,A=S.get("businessDate"),_=Number(S.get("operationTimestamp")),T=S.get("clientTempId");if(H==="clearCache")return await o.clearCache(),x({status:"OK",intent:"clearCache"});if(!T)return x({error:"clientTempId required"},{status:400});if(H!=="create"&&(!R||Number.isNaN(R)))return x({error:"Invalid reportHubId"},{status:400});switch(H){case"create":{if(!A)return x({error:"businessDate required"},{status:400});let w=await o.createDailyReport(b,A,T);return x({status:"OK",intent:"create",report:w,reportHubId:String(w.reportHubId),clientTempId:T})}case"update":{let w=S.get("title"),Y=S.get("content");try{return await o.updateDailyReport(R,b,{title:w,content:Y},T),x({status:"OK",intent:"update",reportHubId:String(R),clientTempId:T})}catch(q){if(q instanceof Error){if(q.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(q.message==="Not Found")return x({error:"Report not found"},{status:404})}throw q}}case"publish":try{let w=await o.publishDailyReport(R,b,T);return x({status:"OK",intent:"publish",reportHubId:String(R),clientTempId:T,report:w})}catch(w){if(w instanceof Error){if(w.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(w.message==="Not Found")return x({error:"Report not found"},{status:404})}throw w}case"delete":try{return await o.deleteDailyReport(R,b,T),x({status:"OK",intent:"delete",reportHubId:String(R),clientTempId:T})}catch(w){if(w instanceof Error){if(w.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(w.message==="Not Found")return x({error:"Report not found"},{status:404})}throw w}case"toggleStar":{let w=S.get("isStarred");if(w===null)return x({error:"isStarred required"},{status:400});let Y=w==="true",q=await o.setStarStatus(b,R,A,Y,T);return x({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:q.isStarred,isRead:q.isRead},operationTimestamp:_,reportHubId:String(R),clientTempId:T})}case"toggleRead":{let w=S.get("isRead");if(w===null)return x({error:"isRead required"},{status:400});let Y=w==="true",q=await o.setReadStatus(b,R,A,Y,T);return x({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:q.isStarred,isRead:q.isRead},operationTimestamp:_,reportHubId:String(R),clientTempId:T})}case"addComment":{let w=S.get("content");if(!w)return x({error:"Content required"},{status:400});let Y=await o.addComment(b,R,w,A,T),q={...Y,userId:Y.userId};return x({status:"OK",intent:"addComment",newComment:q,reportHubId:String(R),clientTempId:T})}case"deleteComment":{let w=Number(S.get("commentId"));if(!w||Number.isNaN(w))return x({error:"Invalid commentId"},{status:400});try{return await o.deleteComment(b,R,w,A,T),x({status:"OK",reportHubId:String(R),deletedCommentId:String(w),clientTempId:T})}catch(Y){if(Y instanceof Error){if(Y.message==="Unauthorized")return x({error:"Unauthorized"},{status:403});if(Y.message==="Not Found")return x({error:"Comment not found"},{status:404})}throw Y}}default:return x({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:M,params:U})=>{let{user:v}=await e(M,{failureRedirect:null});if(!v)return new Response("Unauthorized",{status:401});let k=await o.getUserIdByExternalId(v.id);if(!k)return new Response("Forbidden",{status:403});if(U.endpoint!=="updates")return new Response("Not Found",{status:404});let S=new URL(M.url).searchParams.get("lastEventId")||M.headers.get("Last-Event-ID"),H=new TextEncoder,E=null,R=null,A=null,_=!1,T=()=>{if(!_){if(_=!0,R&&(clearInterval(R),R=null),A&&(A(),A=null),E)try{E.desiredSize!==null&&E.close()}catch{}finally{E=null}_=!1}},w=(q,Q)=>{if(Q.data)try{let I=JSON.parse(Q.data),X=Ge.safeParse(I);if(!X.success){c.error("SSE message validation failed:",X.error.format());return}let V=X.data,ae=typeof I.recipientRawUserId=="number"?I.recipientRawUserId:void 0;if(V.type==="status-update"){if(ae===void 0||ae!==k)return}else if(ae!==void 0&&ae!==k)return;let de;if("recipientRawUserId"in I){let{recipientRawUserId:ge,...oe}=I;de=JSON.stringify(oe)}else de=Q.data;E&&E.desiredSize!==null&&E.enqueue(H.encode(`id: ${q}
|
|
2
|
+
data: ${de}
|
|
3
3
|
|
|
4
|
-
`))}catch(
|
|
4
|
+
`))}catch(I){c.error(`[SSE:${k}] processEntry error:`,I)}},Y=new ReadableStream({async start(q){E=q,R=setInterval(()=>{try{E&&E.desiredSize!==null?E.enqueue(H.encode(`: keep-alive
|
|
5
5
|
|
|
6
|
-
`)):
|
|
6
|
+
`)):T()}catch{T()}},5e3),M.signal.addEventListener("abort",()=>{T()});let Q=S||"0-0";if(A=y.subscribe(I=>{we(I.id,Q)||(Q=I.id,w(I.id,I.message))},I=>{c.error(`[SSE:${k}] Fan-Out reader error:`,I),T()}),!S)try{let I=await p?.getClient();if(I){let X=await I.xRevRange(L,"+","-",{COUNT:1});X.length>0&&!we(X[0].id,Q)&&(Q=X[0].id)}}catch{}if(E&&E.desiredSize!==null){let I=`data: ${JSON.stringify({type:"connected"})}
|
|
7
7
|
|
|
8
|
-
`,Q
|
|
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});
|
|
8
|
+
`,X=Q!=="0-0"?`id: ${Q}
|
|
9
|
+
${I}`:I;E.enqueue(H.encode(X))}if(S)try{let I=await p?.getClient();if(I){let X=await I.xRange(L,S,"+",{COUNT:1e3});for(let V of X)V.id!==S&&(we(V.id,Q)||(Q=V.id,w(V.id,V.message)))}}catch(I){c.error(`[SSE:${k}] catch-up xRange error:`,I)}},cancel(){T()}});return new Response(Y,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}},attachment:{loader:async({request:M,params:U})=>{let v=null,k=(b,S,H)=>{let E=new Headers({"Content-Type":"application/json"});return H!==void 0&&E.set("Retry-After",String(H)),v&&E.append("Set-Cookie",v),new Response(JSON.stringify({error:{message:S}}),{status:b,headers:E})};try{let{user:b,cookie:S}=await e(M,{failureRedirect:null});if(v=S??null,!b)return k(401,"Unauthorized");if(M.method!=="GET"&&M.method!=="HEAD")return k(405,"Method not allowed");let H=r.attachmentIdCodec,E=r.readAttachment;if(!(H&&E))return k(404,"Attachment not found");let R=U.token??"",A=H.decode(R);if(A===null||!Number.isSafeInteger(A)||A<=0)return k(400,"Invalid attachment token");let _=await o.getUserIdByExternalId(b.id);if(!_)return k(403,"Forbidden");if(!K(_,Date.now()))return $.error(`429 attachment=${A} viewer=${_} reason=rate_limit`),k(429,"Too many requests",Nt);let T=await o.getAttachmentForUser(A,_);if(!T)return $.error(`404 attachment=${A} viewer=${_} reason=not_visible`),k(404,"Attachment not found");if(T.fileSize!=null&&T.fileSize>m)return $.error(`413 attachment=${A} viewer=${_} reason=db_size`),k(413,"Attachment too large");if(!j.tryAcquire())return $.error(`503 attachment=${A} viewer=${_} reason=concurrency`),k(503,"Too many concurrent downloads",xt);let w=!1,Y=()=>{w||(w=!0,j.release())},q=!1;try{let Q=M.method==="HEAD",I=await E(T.filePath,{maxBytes:m,head:Q,principal:l(_)});if(!I.ok){let se=Bt(I.reason);return I.reason==="not_found"&&o.markAttachmentMissing(A).catch(pe=>{$.error(`markAttachmentMissing failed attachment=${A} message=${pe instanceof Error?pe.message:"unknown"}`)}),$.error(`${se} attachment=${A} viewer=${_} reason=${I.reason} code=${I.code??"-"}`),k(se,Ut[se]??"Attachment storage unavailable")}let X=Ye(T.fileType)??Ye(I.contentType)??"application/octet-stream",V=Lt.has(X),ae=new URL(M.url).searchParams.get("download")==="1",de=V?X:"application/octet-stream",ge=V&&!ae?"inline":"attachment",oe=I.size??I.bytes.byteLength,ue=new Headers({"Content-Type":de,"Content-Length":String(oe),"Content-Disposition":`${ge}; filename="${Ze(T.fileName)}"; filename*=UTF-8''${Ve(T.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return v&&ue.append("Set-Cookie",v),o.markAttachmentPresent(A).catch(se=>{$.error(`markAttachmentPresent failed attachment=${A} message=${se instanceof Error?se.message:"unknown"}`)}),$.info(`200 attachment=${A} viewer=${_} type=${de} disposition=${ge} bytes=${oe}`),Q?new Response(null,{status:200,headers:ue}):(q=!0,new Response(Yt(I.bytes,Y,vt),{status:200,headers:ue}))}finally{q||Y()}}catch(b){if(b instanceof Response)throw b;return $.error(`500 attachment=? viewer=? reason=unexpected message=${b instanceof Error?b.message:"unknown"}`),k(500,"Attachment request failed")}}}}}var a=require("drizzle-orm");var me=r=>(0,a.getColumns)(r);function ze(r){let{db:e,tables:o,userTable:l,resolveUserId:p,encodeUserId:y,redis:L,cache:h,epochs:O}=r,{hub:c,internal:$,comment:m,label:K,hubLabel:j,userStatus:B}=o,he=r.externalSources??[],Ae=r.draftLabelNames&&r.draftLabelNames.length>0?r.draftLabelNames:[r.draftLabelName??"\u4E0B\u66F8\u304D"],_e=Ae[0]??"\u4E0B\u66F8\u304D",W=r.logger??re(1,"[DailyReportService]"),fe="daily-report:ids",M=r.idsTtlMs??18e4,U="daily-report:ids:epoch",v="daily-report:business-date:",k=r.businessDateTtlMs??3e5,b="daily-report:date-epoch:",S="daily-report:detail-epoch:",H=r.streamKey??"daily-report:sse-stream",E=r.streamMaxLen??1e4,R=t=>O.incrementEpoch(t),A=async(t,n)=>{let s=await L?.getClient();if(!s){W.warn(`[SSE] Redis client unavailable (${n})`);return}let u=Date.now();try{await s.xAdd(H,"*",{data:JSON.stringify(t)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:E}});let g=Date.now()-u;g>1e3&&W.warn(`[SSE] Slow publish (${n}): ${g}ms`)}catch(g){W.error(`[SSE] Redis publish failed (${n}):`,g)}},_=(t,n)=>{if(!t)return null;let s=t instanceof Date?t:new Date(t);if(Number.isNaN(s.getTime()))return typeof t=="string"?t: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"?s.toLocaleString("ja-JP",u):s.toLocaleDateString("ja-JP",u)).replace(/\//g,"-")},T=t=>t==null||t===""?null:/^\d+$/.test(t)?y(Number(t)):t,w=()=>{let t={};for(let n of he)t[`ext_${n.sourceType}`]=me(n.table);return t},Y=t=>{let n=t;for(let s of he)n=n.leftJoin(s.table,(0,a.and)((0,a.eq)(c.sourceType,s.sourceType),(0,a.eq)(c.sourceIdNum,s.idColumn)));return n},q=(t,n)=>{let{hub:s,internal:u}=t,g=s.summary,f=[],D=null,C=null,z=null,J=null,P=null,te=null,ie=[],ce=he.find(N=>N.sourceType===s.sourceType),ye=ce?t[`ext_${ce.sourceType}`]:void 0;if(ce&&ye){let N=ce.mapRow(ye);N.content!==void 0&&(g=N.content),N.employeeName!==void 0&&(te=N.employeeName),N.category!==void 0&&(D=N.category),N.creationCategory!==void 0&&(C=N.creationCategory),N.visitTimeFrom!==void 0&&(z=N.visitTimeFrom),N.visitTimeTo!==void 0&&(J=N.visitTimeTo),N.customerName!==void 0&&(P=N.customerName),N.interviewers!==void 0&&(f=N.interviewers),N.comments!==void 0&&(ie=N.comments)}else s.sourceType==="Internal"&&u&&(g=u.body);let le=(t.labels??[]).map(N=>({id:N.id,name:N.name,color:N.color})),Z=t.comments??[],F=C?Ae.includes(C):!1,G=oe?.[0]??null;return F&&G&&!le.some(N=>N.id===G)&&le.push({id:G,name:_e,color:null}),{reportHubId:s.id,date:_(s.businessDate,"YYYY-MM-DD"),author:t.creatorName??T(s.createdBy)??"",userId:s.userId?y(s.userId):"",sourceType:s.sourceType??"Internal",createdAt:_(s.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:_(s.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:T(s.updatedBy),employeeName:te??t.creatorName??T(s.createdBy),category:D,creationCategory:C,visitTimeFrom:z,visitTimeTo:J,customerName:P,interviewers:f,subject:s.title,content:g,comments:ie,isRead:t.isRead??!1,isStarred:t.isStarred??!1,labels:le,commentItems:Z.map(N=>({...N,userId:y(N.userId),isMine:n?N.userId===n:!1})),attachments:t.attachments}},Q=async t=>{let n=(0,a.aliasedTable)(j,"draft_label"),s=await se();return(await e.select({reportHubId:c.id,businessDate:c.businessDate,sourceType:c.sourceType}).from(c).leftJoin(n,(0,a.and)((0,a.eq)(n.hubId,c.id),(0,a.inArray)(n.labelId,s))).where((0,a.and)((0,a.isNull)(c.deletedAt),(0,a.or)((0,a.eq)(c.userId,t),(0,a.isNull)(c.userId),(0,a.isNull)(n.hubId)))).orderBy((0,a.desc)(c.businessDate),(0,a.desc)(c.id))).map(g=>({...g,businessDate:_(g.businessDate,"YYYY-MM-DD")}))},I=async t=>{let n=await Y(e.select({hub:me(c),internal:me($),creatorName:l.displayName,...w()}).from(c)).leftJoin($,(0,a.eq)(c.id,$.hubId)).leftJoin(l,(0,a.eq)(c.userId,l.id)).where((0,a.and)((0,a.eq)(c.businessDate,a.sql`${t}`),(0,a.isNull)(c.deletedAt))).orderBy((0,a.desc)(c.id)),s=await Ce(n.map(u=>u.hub.id));return n.map(u=>q({...u,attachments:s.get(u.hub.id)??[]}))},X=t=>`${v}${t}`,V=new Map,ae=async t=>{if(!r.disableUserIdCache&&V.has(t))return V.get(t)??null;let n=await p(t);return n!==null&&!r.disableUserIdCache&&V.set(t,n),n},de=async(t,{forceRefresh:n=!1,snapshot:s=!1,ttlMsOverride:u}={})=>{let g=await ae(t);if(!g)return[];let f=`${fe}:user:${g}`;return h.getOrFetch({cacheKey:f,fetcher:async()=>await Q(g),forceRefresh:n,snapshot:s,ttlMsOverride:u??M,epochKey:U})},ge=(t,{forceRefresh:n=!1,snapshot:s=!1,ttlMsOverride:u}={})=>{let g=ee(t);return g?h.getOrFetch({cacheKey:X(g),fetcher:()=>I(g),forceRefresh:n,snapshot:s,ttlMsOverride:u??k}):Promise.resolve([])},oe=null,ue=async()=>(oe!==null||(oe=(await e.select({id:K.id}).from(K).where((0,a.inArray)(K.name,Ae)).orderBy(K.id)).map(n=>n.id)),oe),se=async()=>{let t=await ue();return t.length>0?t:[-1]},pe=async()=>{let t=await ue();if(t.length===0)return null;let[n]=await e.select({id:K.id}).top(1).from(K).where((0,a.eq)(K.name,_e));return n?.id??t[0]},tt=(t,n)=>n!=null?"absent":t!=null?"present":"unknown",Ce=async t=>{let n=new Map,s=o.attachment,u=r.attachmentIdCodec;if(t.length===0||!s||!u)return n;let g=await e.select({id:s.id,hubId:s.hubId,fileName:s.fileName,fileType:s.fileType,fileSize:s.fileSize,createdAt:s.createdAt,objectCheckedAt:s.objectCheckedAt,objectMissingAt:s.objectMissingAt}).from(s).where((0,a.inArray)(s.hubId,t)).orderBy((0,a.asc)(s.createdAt),(0,a.asc)(s.id));for(let f of g){let D={id:u.encode(Number(f.id)),fileName:String(f.fileName),fileType:f.fileType?String(f.fileType):null,fileSize:f.fileSize!=null?Number(f.fileSize):null,createdAt:_(f.createdAt,"YYYY-MM-DD HH:mm:ss"),state:tt(f.objectCheckedAt,f.objectMissingAt)},C=n.get(Number(f.hubId));C?C.push(D):n.set(Number(f.hubId),[D])}return n},rt=async(t,n)=>{let s=o.attachment;if(!s)return null;let u=await se(),g=(0,a.aliasedTable)(j,"draft_label");return(await e.select({fileName:s.fileName,filePath:s.filePath,fileType:s.fileType,fileSize:s.fileSize}).top(1).from(s).innerJoin(c,(0,a.eq)(c.id,s.hubId)).leftJoin(g,(0,a.and)((0,a.eq)(g.hubId,c.id),(0,a.inArray)(g.labelId,u))).where((0,a.and)((0,a.eq)(s.id,t),(0,a.isNull)(c.deletedAt),(0,a.or)((0,a.eq)(c.userId,n),(0,a.isNull)(g.hubId)))))[0]??null},nt=async t=>{let n=o.attachment;if(!n)return;let s=new Date;try{await e.update(n).set({objectCheckedAt:s,objectMissingAt:s,updatedAt:s}).where((0,a.eq)(n.id,t))}catch(u){W.error("markAttachmentMissing failed",u)}},at=async t=>{let n=o.attachment;if(!n)return;let s=new Date;try{await e.update(n).set({objectCheckedAt:s,objectMissingAt:null,updatedAt:s}).where((0,a.eq)(n.id,t))}catch(u){W.error("markAttachmentPresent failed",u)}},ot=async(t,n,{forceRefresh:s=!1,snapshot:u=!1,ttlMsOverride:g}={})=>{let f=await ae(n);if(!f)return[];let D=ee(t);if(!D)return[];let C=`daily-report:date:${D}:user:${f}`;return h.getOrFetch({cacheKey:C,fetcher:async()=>{let z=await se(),J=(0,a.aliasedTable)(j,"draft_label"),P=await Y(e.select({hub:me(c),internal:me($),isRead:B.isRead,isStarred:B.isStarred,creatorName:l.displayName,...w()}).from(c)).leftJoin($,(0,a.eq)(c.id,$.hubId)).leftJoin(B,(0,a.and)((0,a.eq)(c.id,B.hubId),(0,a.eq)(B.userId,f))).leftJoin(J,(0,a.and)((0,a.eq)(J.hubId,c.id),(0,a.inArray)(J.labelId,z))).leftJoin(l,(0,a.eq)(c.userId,l.id)).where((0,a.and)((0,a.eq)(c.businessDate,a.sql`${D}`),(0,a.isNull)(c.deletedAt),(0,a.or)((0,a.eq)(c.userId,f),(0,a.isNull)(J.hubId)))).orderBy((0,a.desc)(c.id));if(P.length===0)return[];let te=P.map(F=>F.hub.id),ie=await e.select({hubId:j.hubId,id:K.id,name:K.name,color:K.color}).from(j).innerJoin(K,(0,a.eq)(j.labelId,K.id)).where((0,a.inArray)(j.hubId,te)),ce=await e.select({hubId:m.hubId,id:m.id,body:m.body,createdAt:m.createdAt,userId:m.userId,userName:l.displayName}).from(m).leftJoin(l,(0,a.eq)(m.userId,l.id)).where((0,a.inArray)(m.hubId,te)).orderBy((0,a.asc)(m.createdAt)),ye=await Ce(te),le=new Map,Z=new Map;for(let F of ie){let G=le.get(F.hubId);G||(G=[],le.set(F.hubId,G)),G.push({id:F.id,name:F.name,color:F.color})}for(let F of ce){let G=Z.get(F.hubId);G||(G=[],Z.set(F.hubId,G)),G.push({id:F.id,content:F.body,createdAt:_(F.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:F.userId,userName:F.userName||""})}return P.map(F=>{let G=F.hub.id;return q({...F,attachments:ye.get(G)??[],labels:le.get(G)||[],comments:Z.get(G)||[]},f)})},forceRefresh:s,snapshot:u,ttlMsOverride:g??k,epochKey:`${b}${D}`})},be=async(t,n,{forceRefresh:s=!1,snapshot:u=!1,ttlMsOverride:g}={})=>{let f=`daily-report:detail:${t}:user:${n}`;return(await h.getOrFetch({cacheKey:f,fetcher:async()=>{let C=await se(),z=(0,a.aliasedTable)(j,"draft_label"),J=await Y(e.select({hub:me(c),internal:me($),isRead:B.isRead,isStarred:B.isStarred,creatorName:l.displayName,...w()}).from(c)).leftJoin($,(0,a.eq)(c.id,$.hubId)).leftJoin(B,(0,a.and)((0,a.eq)(c.id,B.hubId),(0,a.eq)(B.userId,n))).leftJoin(z,(0,a.and)((0,a.eq)(z.hubId,c.id),(0,a.inArray)(z.labelId,C))).leftJoin(l,(0,a.eq)(c.userId,l.id)).where((0,a.and)((0,a.eq)(c.id,t),(0,a.isNull)(c.deletedAt),(0,a.or)((0,a.eq)(c.userId,n),(0,a.isNull)(z.hubId))));if(J.length===0)return[];let P=J[0].hub.id,te=await e.select({id:K.id,name:K.name,color:K.color}).from(j).innerJoin(K,(0,a.eq)(j.labelId,K.id)).where((0,a.eq)(j.hubId,P)),ie=await e.select({id:m.id,body:m.body,createdAt:m.createdAt,userId:m.userId,userName:l.displayName}).from(m).leftJoin(l,(0,a.eq)(m.userId,l.id)).where((0,a.eq)(m.hubId,P)).orderBy((0,a.asc)(m.createdAt)),ce=await Ce([P]),ye=te.map(Z=>({id:Z.id,name:Z.name,color:Z.color})),le=ie.map(Z=>({id:Z.id,content:Z.body,createdAt:_(Z.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:Z.userId,userName:Z.userName||""}));return[q({...J[0],attachments:ce.get(P)??[],labels:ye,comments:le},n)]},forceRefresh:s,snapshot:u,ttlMsOverride:g??k,epochKey:`${S}${t}`}))[0]??null},st=async(t,n,s={})=>{let u=await ae(n);return u?be(t,u,s):null},it=async(t,n,s,u,g)=>{let f=await e.select().top(1).from(B).where((0,a.and)((0,a.eq)(B.hubId,n),(0,a.eq)(B.userId,t))),D;if(f.length>0?f[0].isStarred!==u?D=(await e.update(B).set({isStarred:u,updatedAt:new Date,updatedBy:String(t)}).output().where((0,a.and)((0,a.eq)(B.hubId,n),(0,a.eq)(B.userId,t))))[0]:D=f[0]:D=(await e.insert(B).output().values({hubId:n,userId:t,isStarred:u,isRead:!1,createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}))[0],s){let C=ee(s);C&&(h.invalidate(`daily-report:date:${C}:user:${t}`),await R(`${b}${C}`))}return h.invalidate(`daily-report:detail:${n}`),h.invalidate(`daily-report:detail:${n}:user:${t}`),await R(`${S}${n}`),await A(Me.parse({type:"status-update",reportHubId:n,recipientRawUserId:t,statusType:"star",value:u,clientTempId:g}),"setStarStatus"),D},lt=async(t,n,s,u,g)=>{let f=await e.select().top(1).from(B).where((0,a.and)((0,a.eq)(B.hubId,n),(0,a.eq)(B.userId,t))),D;if(f.length>0?f[0].isRead!==u?D=(await e.update(B).set({isRead:u,updatedAt:new Date,updatedBy:String(t)}).output().where((0,a.and)((0,a.eq)(B.hubId,n),(0,a.eq)(B.userId,t))))[0]:D=f[0]:D=(await e.insert(B).output().values({hubId:n,userId:t,isRead:u,isStarred:!1,createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}))[0],s){let C=ee(s);C&&(h.invalidate(`daily-report:date:${C}:user:${t}`),await R(`${b}${C}`))}return h.invalidate(`daily-report:detail:${n}`),h.invalidate(`daily-report:detail:${n}:user:${t}`),await R(`${S}${n}`),await A(Me.parse({type:"status-update",reportHubId:n,recipientRawUserId:t,statusType:"read",value:u,clientTempId:g}),"setReadStatus"),D},dt=async(t,n,s,u,g)=>{let[f]=await e.select({sourceType:c.sourceType}).top(1).from(c).where((0,a.eq)(c.id,n));if(f&&f.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let[D]=await e.insert(m).output().values({hubId:n,userId:t,body:s,createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}),[C]=await e.select({displayName:l.displayName}).top(1).from(l).where((0,a.eq)(l.id,t)),z=C?.displayName??"Unknown";if(u){let P=ee(u);P&&(h.invalidatePrefix(`daily-report:date:${P}:user:`),await R(`${b}${P}`))}h.invalidate(`daily-report:detail:${n}`),h.invalidatePrefix(`daily-report:detail:${n}:user:`),await R(`${S}${n}`);let J={id:D.id,userId:y(D.userId),userName:z,content:D.body,createdAt:_(D.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await A($e.parse({type:"comment-add",reportHubId:n,comment:J,clientTempId:g}),"addComment"),J},ut=async(t,n)=>await t.select().top(1).from(m).where((0,a.eq)(m.id,n)),ct=async(t,n,s,u,g)=>{let f=await ut(e,s);if(f.length===0)throw new Error("Not Found");if(f[0].userId!==t)throw new Error("Unauthorized");if(await e.delete(m).where((0,a.eq)(m.id,s)),u){let D=ee(u);D&&(h.invalidatePrefix(`daily-report:date:${D}:user:`),await R(`${b}${D}`))}h.invalidate(`daily-report:detail:${n}`),h.invalidatePrefix(`daily-report:detail:${n}:user:`),await R(`${S}${n}`),await A(Pe.parse({type:"comment-delete",reportHubId:n,commentId:s,clientTempId:g}),"deleteComment")},mt=async(t,n,s)=>{W.info("createDailyReport called",{userId:t,businessDate:n});let[u]=await e.select({displayName:l.displayName}).from(l).where((0,a.eq)(l.id,t)),g=u?.displayName??y(t);try{let f=await e.transaction(async z=>{W.info("Starting transaction");let J=`internal-temp-${Date.now()}-${Math.random()}`,[P]=await z.insert(c).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 z.update(c).set({sourceId:String(P.id)}).where((0,a.eq)(c.id,P.id)),W.info("Hub created",P),await z.insert($).values({hubId:P.id,body:"",createdAt:new Date,createdBy:String(t),updatedAt:new Date,updatedBy:String(t)}),W.info("Internal created"),W.info("Calling getDraftLabelId");let te=await pe();W.info("draftLabelId",te);let ie=[];return te&&(await z.insert(j).values({hubId:P.id,labelId:te,createdAt:new Date,createdBy:String(t)}),ie.push({id:te,name:_e,color:null})),W.info("Label assigned"),{reportHubId:P.id,date:n,createdAt:_(P.createdAt,"YYYY-MM-DD HH:mm:ss"),author:g,userId:y(t),sourceType:"Internal",employeeName:g,updatedBy:y(t),updatedAt:_(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:ie,commentItems:[],attachments:[]}}),D=ee(n);D&&h.invalidate(`daily-report:date:${D}:user:${t}`),h.invalidatePrefix(v),h.invalidate(`${fe}:user:${t}`),await R(U),D&&await R(`${b}${D}`);let C=await be(f.reportHubId,t,{forceRefresh:!0});if(C){let z=await ue(),J=C.labels.some(P=>z.includes(P.id));await A(Be.parse({type:"report-create",reportHubId:C.reportHubId,report:C,clientTempId:s,recipientRawUserId:J?t:void 0}),"createDailyReport")}return C??f}catch(f){throw W.error("Error in createDailyReport",f),f}},Te=async(t,n)=>await t.select().top(1).from(c).where((0,a.eq)(c.id,n)),Ee=async(t,n,s)=>{await t.update(c).set(s).where((0,a.eq)(c.id,n))},Fe=async(t,n,s)=>{await t.update($).set(s).where((0,a.eq)($.hubId,n))},Ke=async(t,n,s)=>{await t.delete(j).where((0,a.and)((0,a.eq)(j.hubId,n),(0,a.eq)(j.labelId,s)))};return{streamKey:H,streamMaxLen:E,clearCache:async()=>{h.clearAll(),V.clear(),oe=null,O&&await R(U),W.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(t,n)=>{h.invalidatePrefix(v);for(let s of new Set(t))h.invalidatePrefix(`daily-report:detail:${s}:user:`),await R(`${S}${s}`);for(let s of new Set(n)){let u=ee(s);u&&await R(`${b}${u}`)}},getUserIdByExternalId:ae,getDailyReportIdsByExternalId:de,getDailyReportsByBusinessDate:ge,getDailyReportsByBusinessDateByExternalId:ot,getDailyReportDetailById:be,getDailyReportDetailByIdByExternalId:st,getDraftLabelId:pe,getAttachmentsByHubIds:Ce,getAttachmentForUser:rt,markAttachmentMissing:nt,markAttachmentPresent:at,setStarStatus:it,setReadStatus:lt,addComment:dt,deleteComment:ct,createDailyReport:mt,updateDailyReport:async(t,n,s,u)=>{let g=await Te(e,t);if(!g.length||g[0].deletedAt)throw new Error("Not Found");if(g[0].userId!==n)throw new Error("Unauthorized");await e.transaction(async D=>{s.title!==void 0&&await Ee(D,t,{title:s.title,updatedAt:new Date,updatedBy:String(n)}),s.content!==void 0&&await Fe(D,t,{body:s.content,updatedAt:new Date,updatedBy:String(n)})}),h.invalidatePrefix(`daily-report:detail:${t}:user:`),h.invalidatePrefix(v);let f=await be(t,n,{forceRefresh:!0});if(f){let D=await ue(),C=f.labels.some(z=>D.includes(z.id));await A(Ue.parse({type:"report-update",reportHubId:f.reportHubId,report:f,clientTempId:u,recipientRawUserId:C?n:void 0}),"updateDailyReport")}},publishDailyReport:async(t,n,s)=>{let u=await Te(e,t);if(!u.length)throw new Error("Not Found");if(u[0].userId!==n)throw new Error("Unauthorized");let g=await pe();if(!g)return null;if(await Ke(e,t,g),h.invalidatePrefix(`daily-report:detail:${t}:user:`),h.invalidatePrefix(v),h.invalidatePrefix(fe),await R(U),u[0].businessDate){let C=ee(_(u[0].businessDate,"YYYY-MM-DD"));C&&await R(`${b}${C}`)}let f=ee(_(u[0].businessDate,"YYYY-MM-DD"));f&&h.invalidate(`daily-report:date:${f}:user:${n}`);let D=await be(t,n,{forceRefresh:!0});return D&&await A(He.parse({type:"report-publish",reportHubId:D.reportHubId,report:D,clientTempId:s}),"publishDailyReport"),D??null},deleteDailyReport:async(t,n,s)=>{let u=await Te(e,t);if(!u.length||u[0].deletedAt)throw new Error("Not Found");if(u[0].userId!==n)throw new Error("Unauthorized");if(await Ee(e,t,{deletedAt:new Date,deletedBy:String(n),updatedAt:new Date,updatedBy:String(n)}),h.invalidatePrefix(`daily-report:detail:${t}:user:`),h.invalidatePrefix(v),h.invalidatePrefix(fe),await R(U),u[0].businessDate){let g=ee(_(u[0].businessDate,"YYYY-MM-DD"));g&&await R(`${b}${g}`)}await A(qe.parse({type:"report-delete",reportHubId:t,clientTempId:s}),"deleteDailyReport")},findDailyReportHubById:Te,updateDailyReportHub:Ee,updateDailyReportInternal:Fe,deleteDailyReportLabel:Ke}}var Se=require("drizzle-orm");function et(r){let e=[],o=r&&r.length>0?r:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let l of o){let y=`daily_report_${l.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:y,name:l.name,description:l.description??`${l.name} daily report access`}),l.includeCommentResource!==!1&&e.push({resourceKey:`${y}_comment`,name:`${l.name} Comment`,description:`${l.name} daily report comment access`})}return e}async function Ot(r,e,o){let l=r,p=e.TMResource,y=o.appKey,L=o.actor??"system:daily-report",h=new Date,O=o.resources??et(o.sources);for(let c of O){let $=await l.select().from(p).where((0,Se.and)((0,Se.eq)(p.appKey,y),(0,Se.eq)(p.resourceKey,c.resourceKey)));(!$||$.length===0)&&await l.insert(p).values({appKey:y,resourceKey:c.resourceKey,name:c.name,description:c.description??null,createdAt:h,createdBy:L,updatedAt:h,updatedBy:L})}}var zt=re(1,"[DailyReportExternalSource]"),Ft=(r,e,o,l=zt)=>{if(!r)return[];try{let p=JSON.parse(r);return Array.isArray(p)?p.map(o).filter(y=>y!==null):(l.warn(`Unexpected ${e} format: not an array`),[])}catch(p){return l.warn(`Failed to parse ${e}:`,p),[]}};var Ie=require("drizzle-orm"),i=require("drizzle-orm/mssql-core");function Kt(r,e){let o=(0,i.mssqlSchema)(r),l=e.userTable,p=o.table("DailyReportHub",{id:(0,i.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,i.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,i.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,i.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(Ie.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,i.date)("business_date"),userId:(0,i.bigint)("user_id",{mode:"number"}),title:(0,i.nvarchar)("title",{length:200}),summary:(0,i.nvarchar)("summary",{length:"max"}),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,i.datetime2)("updated_at").notNull(),updatedBy:(0,i.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,i.datetime2)("deleted_at"),deletedBy:(0,i.nvarchar)("deleted_by",{length:50})},m=>[(0,i.primaryKey)({name:`${r}_DailyReportHub_pk`,columns:[m.id]}),(0,i.foreignKey)({name:`${r}_DailyReportHub_user_id_fk`,columns:[m.userId],foreignColumns:[l.id]}),(0,i.index)(`${r}_DailyReportHub_business_date_index`).on(m.businessDate),(0,i.index)(`${r}_DailyReportHub_updated_at_index`).on(m.updatedAt),(0,i.index)(`${r}_DailyReportHub_source_index`).on(m.sourceType,m.sourceId),(0,i.index)(`${r}_DailyReportHub_user_id_index`).on(m.userId),(0,i.index)(`${r}_DailyReportHub_business_date_id_index`).on((0,Ie.desc)(m.businessDate),(0,Ie.desc)(m.id)),(0,i.index)(`${r}_DailyReportHub_deleted_at_index`).on(m.deletedAt)]),y=o.table("DailyReportInternal",{hubId:(0,i.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,i.nvarchar)("body",{length:"max"}),metadata:(0,i.nvarchar)("metadata",{length:"max"}),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,i.datetime2)("updated_at").notNull(),updatedBy:(0,i.nvarchar)("updated_by",{length:50}).notNull()},m=>[(0,i.primaryKey)({name:`${r}_DailyReportInternal_pk`,columns:[m.hubId]}),(0,i.foreignKey)({name:`${r}_DailyReportInternal_hub_id_fk`,columns:[m.hubId],foreignColumns:[p.id]})]),L=o.table("DailyReportComment",{id:(0,i.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,i.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,i.bigint)("user_id",{mode:"number"}).notNull(),body:(0,i.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,i.datetime2)("updated_at").notNull(),updatedBy:(0,i.nvarchar)("updated_by",{length:50}).notNull()},m=>[(0,i.primaryKey)({name:`${r}_DailyReportComment_pk`,columns:[m.id]}),(0,i.foreignKey)({name:`${r}_DailyReportComment_hub_id_fk`,columns:[m.hubId],foreignColumns:[p.id]}),(0,i.foreignKey)({name:`${r}_DailyReportComment_user_id_fk`,columns:[m.userId],foreignColumns:[l.id]}),(0,i.index)(`${r}_DailyReportComment_hub_id_index`).on(m.hubId)]),h=o.table("DailyReportLabel",{id:(0,i.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,i.bigint)("user_id",{mode:"number"}),name:(0,i.nvarchar)("name",{length:50}).notNull(),color:(0,i.nvarchar)("color",{length:20}),sortOrder:(0,i.int)("sort_order"),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,i.datetime2)("updated_at").notNull(),updatedBy:(0,i.nvarchar)("updated_by",{length:50}).notNull()},m=>[(0,i.primaryKey)({name:`${r}_DailyReportLabel_pk`,columns:[m.id]}),(0,i.foreignKey)({name:`${r}_DailyReportLabel_user_id_fk`,columns:[m.userId],foreignColumns:[l.id]})]),O=o.table("DailyReportHub_Label",{hubId:(0,i.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,i.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull()},m=>[(0,i.primaryKey)({name:`${r}_DailyReportHub_Label_pk`,columns:[m.hubId,m.labelId]}),(0,i.foreignKey)({name:`${r}_DailyReportHub_Label_hub_id_fk`,columns:[m.hubId],foreignColumns:[p.id]}),(0,i.foreignKey)({name:`${r}_DailyReportHub_Label_label_id_fk`,columns:[m.labelId],foreignColumns:[h.id]})]),c=o.table("DailyReportUserStatus",{hubId:(0,i.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,i.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,i.bit)("is_read").default(!1).notNull(),isStarred:(0,i.bit)("is_starred").default(!1).notNull(),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,i.datetime2)("updated_at").notNull(),updatedBy:(0,i.nvarchar)("updated_by",{length:50}).notNull()},m=>[(0,i.primaryKey)({name:`${r}_DailyReportUserStatus_pk`,columns:[m.hubId,m.userId]}),(0,i.foreignKey)({name:`${r}_DailyReportUserStatus_hub_id_fk`,columns:[m.hubId],foreignColumns:[p.id]}),(0,i.foreignKey)({name:`${r}_DailyReportUserStatus_user_id_fk`,columns:[m.userId],foreignColumns:[l.id]})]),$=o.table("DailyReportAttachment",{id:(0,i.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,i.bigint)("hub_id",{mode:"number"}).notNull(),uploadedBy:(0,i.bigint)("uploaded_by",{mode:"number"}),sourceKey:(0,i.nvarchar)("source_key",{length:200}).notNull(),fileName:(0,i.nvarchar)("file_name",{length:255}).notNull(),filePath:(0,i.nvarchar)("file_path",{length:"max"}).notNull(),fileType:(0,i.nvarchar)("file_type",{length:100}),fileSize:(0,i.bigint)("file_size",{mode:"number"}),objectCheckedAt:(0,i.datetime2)("object_checked_at"),objectMissingAt:(0,i.datetime2)("object_missing_at"),createdAt:(0,i.datetime2)("created_at").notNull(),createdBy:(0,i.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,i.datetime2)("updated_at").notNull(),updatedBy:(0,i.nvarchar)("updated_by",{length:50}).notNull()},m=>[(0,i.primaryKey)({name:`${r}_DailyReportAttachment_pk`,columns:[m.id]}),(0,i.foreignKey)({name:`${r}_DailyReportAttachment_hub_id_fk`,columns:[m.hubId],foreignColumns:[p.id]}),(0,i.foreignKey)({name:`${r}_DailyReportAttachment_uploaded_by_fk`,columns:[m.uploadedBy],foreignColumns:[l.id]}),(0,i.uniqueIndex)(`${r}_DailyReportAttachment_source_unique`).on(m.hubId,m.sourceKey),(0,i.index)(`${r}_DailyReportAttachment_hub_id_index`).on(m.hubId,m.createdAt)]);return{hub:p,internal:y,comment:L,attachment:$,label:h,hubLabel:O,userStatus:c}}function jt(r){let e=xe(r.redis),o=new Re({defaultTtlMs:r.cacheDefaultTtlMs??6e4},e),l=ze({...r,cache:o,epochs:e}),p=new De({redis:r.redis,streamKey:l.streamKey,cache:o,logger:r.logger}),y=Oe({authenticate:r.authenticate,service:l,encodeUserId:r.encodeUserId,attachmentIdCodec:r.attachmentIdCodec,readAttachment:r.readAttachment,attachmentMaxBytes:r.attachmentMaxBytes,attachmentRateLimitPerMinute:r.attachmentRateLimitPerMinute,attachmentConcurrency:r.attachmentConcurrency,redis:r.redis,sseReader:p,streamKey:l.streamKey,loginRedirectPath:r.loginRedirectPath,logger:r.logger});return{service:l,cache:o,epochs:e,sseReader:p,streamKey:l.streamKey,...y}}0&&(module.exports={DailyReportSseReader,SqlResultCache,asciiFallbackFileName,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,encodeRfc8187,generateETag,isStreamIdLte,jsonResponseWithETag,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
|
|
10
10
|
//# sourceMappingURL=server.js.map
|