@aiquants/daily-report 0.3.0 → 0.3.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/dist/server.mjs CHANGED
@@ -1,4 +1,4 @@
1
- var He=n=>({async getEpoch(t){try{let o=await n?.getClient();if(!o)return 0;let s=await o.get(t);return s?Number(s):0}catch{return 0}},async incrementEpoch(t){try{let o=await n?.getClient();if(!o)return;await o.incr(t)}catch{}}}),we=class{constructor(t,o){this.config=t;this.epochStore=o;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:o,forceRefresh:s,snapshot:g}=t,y=this.buckets.get(o);if(s&&(this.buckets.delete(o),this.inFlight.delete(o)),!s&&y&&y.expireAt>Date.now())if(t.epochKey){let d=await this.epochStore.getEpoch(t.epochKey);if(y.epoch===d)return g?y.records.map(W=>structuredClone(W)):y.records;this.buckets.delete(o)}else return g?y.records.map(d=>structuredClone(d)):y.records;if(!s&&this.inFlight.has(o)){let d=await this.inFlight.get(o);return g?d.map(W=>structuredClone(W)):d}let O;O=(async()=>{let d=await t.fetcher();if(s||this.inFlight.get(o)===O){let W=Date.now()+(t.ttlMsOverride??this.config.defaultTtlMs),u=t.epochKey?await this.epochStore.getEpoch(t.epochKey):0;this.buckets.set(o,{records:d,expireAt:W,epoch:u})}return d})(),s||this.inFlight.set(o,O);try{let d=await O;return g?d.map(W=>structuredClone(W)):d}finally{this.inFlight.delete(o)}};this.flush=t=>{this.buckets.delete(t),this.inFlight.delete(t)};this.invalidatePrefix=t=>{for(let o of this.buckets.keys())o.startsWith(t)&&this.buckets.delete(o);for(let o of this.inFlight.keys())o.startsWith(t)&&this.inFlight.delete(o)}}};var dt=/^\d{4}-\d{2}-\d{2}$/,ut=/^\d{4}\/\d{2}\/\d{2}$/,Ye=n=>n<10?`0${n}`:`${n}`,qe=n=>{if(Number.isNaN(n.getTime()))return null;let t=n.getFullYear(),o=Ye(n.getMonth()+1),s=Ye(n.getDate());return`${t}-${o}-${s}`},V=n=>{if(n==null)return null;if(n instanceof Date)return qe(n);let t=n.trim();if(t==="")return null;if(dt.test(t))return t;if(ut.test(t))return t.replaceAll("/","-");let o=new Date(t);return qe(o)};var ne=(n,t,o=console)=>{let s=g=>typeof g=="string"?[`${t} ${g}`]:[t,g];return{debug:(g,...y)=>{n<=0&&o.debug(...s(g),...y)},info:(g,...y)=>{n<=1&&o.info(...s(g),...y)},warn:(g,...y)=>{n<=2&&o.warn(...s(g),...y)},error:(g,...y)=>{n<=3&&o.error(...s(g),...y)}}};import{z as a}from"zod";var ct=a.object({name:a.string(),affiliation:a.string().nullable()}),pt=a.object({name:a.string().nullable(),text:a.string().nullable(),color:a.string().nullable()}),mt=a.object({id:a.number(),name:a.string(),color:a.string().nullable()}),Oe=a.object({id:a.number(),userId:a.string(),userName:a.string(),content:a.string(),createdAt:a.string(),isMine:a.boolean()}),Me=a.object({reportHubId:a.number(),date:a.string().nullable(),createdAt:a.string().nullable(),author:a.string(),userId:a.string(),sourceType:a.string().nullable(),employeeName:a.string().nullable(),updatedBy:a.string().nullable(),updatedAt:a.string().nullable(),category:a.string().nullable(),creationCategory:a.string().nullable(),visitTimeFrom:a.string().nullable(),visitTimeTo:a.string().nullable(),customerName:a.string().nullable(),interviewers:a.array(ct),subject:a.string().nullable(),content:a.string().nullable(),comments:a.array(pt),isRead:a.boolean(),isStarred:a.boolean(),labels:a.array(mt),commentItems:a.array(Oe)}),yt=a.object({type:a.literal("connected")}),Se=a.object({type:a.literal("status-update"),reportHubId:a.number(),statusType:a.enum(["star","read"]),value:a.boolean(),clientTempId:a.string(),recipientRawUserId:a.number().optional()}),ve=a.object({type:a.literal("comment-add"),reportHubId:a.number(),comment:Oe,clientTempId:a.string()}),xe=a.object({type:a.literal("comment-delete"),reportHubId:a.number(),commentId:a.number(),clientTempId:a.string()}),Ne=a.object({type:a.literal("report-create"),reportHubId:a.number(),report:Me,clientTempId:a.string(),recipientRawUserId:a.number().optional()}),Ee=a.object({type:a.literal("report-update"),reportHubId:a.number(),report:Me,clientTempId:a.string(),recipientRawUserId:a.number().optional()}),$e=a.object({type:a.literal("report-publish"),reportHubId:a.number(),report:Me,clientTempId:a.string()}),Le=a.object({type:a.literal("report-delete"),reportHubId:a.number(),clientTempId:a.string()}),Fe=a.discriminatedUnion("type",[yt,Se,ve,xe,Ne,Ee,$e,Le]);import{createHash as gt}from"crypto";var Pe=n=>{let t=JSON.stringify(n);return`"${gt("sha256").update(t).digest("hex")}"`};var ft=ne(1,"[Response]"),ae=(n,t,o,s=200,g=ft)=>{let y=Pe(o),O=n.headers.get("If-None-Match");g.info(`[jsonResponseWithETag] ETag: ${y}, If-None-Match: ${O}`);let d=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 t&&d.append("Set-Cookie",t),n.method==="GET"&&s===200&&O===y?new Response(null,{status:304,headers:d}):new Response(JSON.stringify(o),{status:s,headers:d})};import{EventEmitter as bt}from"events";var Ce=(n,t)=>{let[o,s]=n.split("-").map(Number),[g,y]=t.split("-").map(Number);return o!==g?o<g:s<=y},_e=class{constructor(t){this.config=t;this._emitter=new bt;this._state="idle";this._refCount=0;this._lastId="0-0";this._emitter.setMaxListeners(0),this._logger=t.logger??ne(1,"[SSE Reader]")}subscribe(t,o){return this._emitter.on("entry",t),o&&this._emitter.on("error",o),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",t),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(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 o of t)for(let s of o.messages){this._lastId=s.id;try{let g=s.message?.data?JSON.parse(s.message.data):null,y=g?.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 O=g?.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:s.id,message:s.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=(n,t)=>new Response(JSON.stringify(n),{status:t?.status??200,headers:{"Content-Type":"application/json"}});function ze(n){let{authenticate:t,service:o,encodeUserId:s,redis:g,sseReader:y,streamKey:O}=n,d=n.loginRedirectPath??"/auth/login",W=n.logger??ne(3,"[DailyReportAPI]"),u=n.logger??ne(1,"[DailyReportSSE]"),m=async({request:C})=>{let{user:P,cookie:I}=await t(C,{failureRedirect:d}),L=new Headers;I&&L.append("Set-Cookie",I);let _=null;P&&(_=await o.getUserIdByExternalId(P.id));let w=_?s(_):null;return{data:{user:P,userId:w},headers:L}},E={"business-date":async(C,P,I,L)=>{let _=V(C.searchParams.get("businessDate")),w=C.searchParams.get("forceRefresh")==="true";if(!_)return ae(I,P,{error:{message:"Invalid business date"}},400);let k=await o.getDailyReportsByBusinessDateByExternalId(_,L.id,{forceRefresh:w});return ae(I,P,{businessDate:_,reports:k},200)},ids:async(C,P,I,L)=>{let _=C.searchParams.get("forceRefresh")==="true",w=await o.getDailyReportIdsByExternalId(L.id,{forceRefresh:_});return ae(I,P,{ids:w},200)},report:async(C,P,I,L)=>{let _=C.searchParams.get("reportHubId"),w=C.searchParams.get("forceRefresh")==="true",k=_?Number.parseInt(_,10):NaN;if(!Number.isFinite(k)||k<=0)return ae(I,P,{error:{message:"Invalid reportHubId"}},400);let v=await o.getDailyReportDetailByIdByExternalId(k,L.id,{snapshot:!0,forceRefresh:w});return v?ae(I,P,{report:v},200):ae(I,P,{error:{message:"Report not found"}},404)}};return{index:{loader:m},api:{loader:async({request:C,params:P})=>{let{user:I,cookie:L}=await t(C,{failureRedirect:null}),_=L??null;if(!I)return ae(C,_,{error:{message:"Unauthorized"}},401);if(C.method!=="GET")return ae(C,_,{error:{message:"Method not allowed"}},405);let w=P.endpoint??"",k=E[w];if(!k)return ae(C,_,{error:{message:"Unknown endpoint"}},404);let v=Date.now();try{let D=new URL(C.url);return await k(D,_,C,I)}catch(D){let q=Date.now()-v,j=D instanceof Error?D:new Error(String(D));return W.error(`500 endpoint=${w} elapsed=${q}ms name=${j.name} code=${"code"in j?j.code:"N/A"} message=${j.message}`),W.error("Stack:",j.stack),ae(C,_,{error:{message:"Internal Server Error"}},500)}},action:async({request:C,params:P})=>{let{user:I}=await t(C,{failureRedirect:null});if(!I)return M({error:"Unauthorized"},{status:401});if(P.endpoint!=="action")return M({error:"Unknown endpoint"},{status:404});let _=await o.getUserIdByExternalId(I.id);if(!_)return M({error:"User not found"},{status:404});let w=await C.formData(),k=w.get("intent"),v=w.get("reportHubId"),D=v?Number(v):NaN,q=w.get("businessDate"),j=Number(w.get("operationTimestamp")),x=w.get("clientTempId");if(!x)return M({error:"clientTempId required"},{status:400});if(k!=="create"&&(!D||Number.isNaN(D)))return M({error:"Invalid reportHubId"},{status:400});switch(k){case"create":{if(!q)return M({error:"businessDate required"},{status:400});let c=await o.createDailyReport(_,q,x);return M({status:"OK",intent:"create",report:c,reportHubId:String(c.reportHubId),clientTempId:x})}case"update":{let c=w.get("title"),$=w.get("content");try{return await o.updateDailyReport(D,_,{title:c,content:$},x),M({status:"OK",intent:"update",reportHubId:String(D),clientTempId:x})}catch(A){if(A instanceof Error){if(A.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(A.message==="Not Found")return M({error:"Report not found"},{status:404})}throw A}}case"publish":try{let c=await o.publishDailyReport(D,_,x);return M({status:"OK",intent:"publish",reportHubId:String(D),clientTempId:x,report:c})}catch(c){if(c instanceof Error){if(c.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(c.message==="Not Found")return M({error:"Report not found"},{status:404})}throw c}case"delete":try{return await o.deleteDailyReport(D,_,x),M({status:"OK",intent:"delete",reportHubId:String(D),clientTempId:x})}catch(c){if(c instanceof Error){if(c.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(c.message==="Not Found")return M({error:"Report not found"},{status:404})}throw c}case"toggleStar":{let c=w.get("isStarred");if(c===null)return M({error:"isStarred required"},{status:400});let $=c==="true",A=await o.setStarStatus(_,D,q,$,x);return M({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:A.isStarred,isRead:A.isRead},operationTimestamp:j,reportHubId:String(D),clientTempId:x})}case"toggleRead":{let c=w.get("isRead");if(c===null)return M({error:"isRead required"},{status:400});let $=c==="true",A=await o.setReadStatus(_,D,q,$,x);return M({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:A.isStarred,isRead:A.isRead},operationTimestamp:j,reportHubId:String(D),clientTempId:x})}case"addComment":{let c=w.get("content");if(!c)return M({error:"Content required"},{status:400});let $=await o.addComment(_,D,c,q,x),A={...$,userId:$.userId};return M({status:"OK",intent:"addComment",newComment:A,reportHubId:String(D),clientTempId:x})}case"deleteComment":{let c=Number(w.get("commentId"));if(!c||Number.isNaN(c))return M({error:"Invalid commentId"},{status:400});try{return await o.deleteComment(_,D,c,q,x),M({status:"OK",reportHubId:String(D),deletedCommentId:String(c),clientTempId:x})}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 $}}default:return M({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:C,params:P})=>{let{user:I}=await t(C,{failureRedirect:null});if(!I)return new Response("Unauthorized",{status:401});let L=await o.getUserIdByExternalId(I.id);if(!L)return new Response("Forbidden",{status:403});if(P.endpoint!=="updates")return new Response("Not Found",{status:404});let w=new URL(C.url).searchParams.get("lastEventId")||C.headers.get("Last-Event-ID"),k=new TextEncoder,v=null,D=null,q=null,j=!1,x=()=>{if(!j){if(j=!0,D&&(clearInterval(D),D=null),q&&(q(),q=null),v)try{v.desiredSize!==null&&v.close()}catch{}finally{v=null}j=!1}},c=(A,K)=>{if(K.data)try{let T=JSON.parse(K.data),Q=Fe.safeParse(T);if(!Q.success){u.error("SSE message validation failed:",Q.error.format());return}let re=Q.data,de=typeof T.recipientRawUserId=="number"?T.recipientRawUserId:void 0;if(re.type==="status-update"){if(de===void 0||de!==L)return}else if(de!==void 0&&de!==L)return;let ye;if("recipientRawUserId"in T){let{recipientRawUserId:ke,...ge}=T;ye=JSON.stringify(ge)}else ye=K.data;v&&v.desiredSize!==null&&v.enqueue(k.encode(`id: ${A}
1
+ var He=n=>({async getEpoch(t){try{let a=await n?.getClient();if(!a)return 0;let s=await a.get(t);return s?Number(s):0}catch{return 0}},async incrementEpoch(t){try{let a=await n?.getClient();if(!a)return;await a.incr(t)}catch{}}}),we=class{constructor(t,a){this.config=t;this.epochStore=a;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:a,forceRefresh:s,snapshot:g}=t,y=this.buckets.get(a);if(s&&(this.buckets.delete(a),this.inFlight.delete(a)),!s&&y&&y.expireAt>Date.now())if(t.epochKey){let d=await this.epochStore.getEpoch(t.epochKey);if(y.epoch===d)return g?y.records.map(W=>structuredClone(W)):y.records;this.buckets.delete(a)}else return g?y.records.map(d=>structuredClone(d)):y.records;if(!s&&this.inFlight.has(a)){let d=await this.inFlight.get(a);return g?d.map(W=>structuredClone(W)):d}let O;O=(async()=>{let d=await t.fetcher();if(s||this.inFlight.get(a)===O){let W=Date.now()+(t.ttlMsOverride??this.config.defaultTtlMs),u=t.epochKey?await this.epochStore.getEpoch(t.epochKey):0;this.buckets.set(a,{records:d,expireAt:W,epoch:u})}return d})(),s||this.inFlight.set(a,O);try{let d=await O;return g?d.map(W=>structuredClone(W)):d}finally{this.inFlight.delete(a)}};this.flush=t=>{this.buckets.delete(t),this.inFlight.delete(t)};this.invalidatePrefix=t=>{for(let a of this.buckets.keys())a.startsWith(t)&&this.buckets.delete(a);for(let a of this.inFlight.keys())a.startsWith(t)&&this.inFlight.delete(a)}}};var dt=/^\d{4}-\d{2}-\d{2}$/,ut=/^\d{4}\/\d{2}\/\d{2}$/,Ye=n=>n<10?`0${n}`:`${n}`,qe=n=>{if(Number.isNaN(n.getTime()))return null;let t=n.getFullYear(),a=Ye(n.getMonth()+1),s=Ye(n.getDate());return`${t}-${a}-${s}`},V=n=>{if(n==null)return null;if(n instanceof Date)return qe(n);let t=n.trim();if(t==="")return null;if(dt.test(t))return t;if(ut.test(t))return t.replaceAll("/","-");let a=new Date(t);return qe(a)};var ne=(n,t,a=console)=>{let s=g=>typeof g=="string"?[`${t} ${g}`]:[t,g];return{debug:(g,...y)=>{n<=0&&a.debug(...s(g),...y)},info:(g,...y)=>{n<=1&&a.info(...s(g),...y)},warn:(g,...y)=>{n<=2&&a.warn(...s(g),...y)},error:(g,...y)=>{n<=3&&a.error(...s(g),...y)}}};import{z as o}from"zod";var ct=o.object({name:o.string(),affiliation:o.string().nullable()}),pt=o.object({name:o.string().nullable(),text:o.string().nullable(),color:o.string().nullable()}),mt=o.object({id:o.number(),name:o.string(),color:o.string().nullable()}),Oe=o.object({id:o.number(),userId:o.string(),userName:o.string(),content:o.string(),createdAt:o.string(),isMine:o.boolean()}),Me=o.object({reportHubId:o.number(),date:o.string().nullable(),createdAt:o.string().nullable(),author:o.string(),userId:o.string(),employeeName:o.string().nullable(),updatedBy:o.string().nullable(),updatedAt:o.string().nullable(),category:o.string().nullable(),creationCategory:o.string().nullable(),visitTimeFrom:o.string().nullable(),visitTimeTo:o.string().nullable(),customerName:o.string().nullable(),interviewers:o.array(ct),subject:o.string().nullable(),content:o.string().nullable(),comments:o.array(pt),isRead:o.boolean(),isStarred:o.boolean(),labels:o.array(mt),commentItems:o.array(Oe)}),yt=o.object({type:o.literal("connected")}),Se=o.object({type:o.literal("status-update"),reportHubId:o.number(),statusType:o.enum(["star","read"]),value:o.boolean(),clientTempId:o.string(),recipientRawUserId:o.number().optional()}),ve=o.object({type:o.literal("comment-add"),reportHubId:o.number(),comment:Oe,clientTempId:o.string()}),xe=o.object({type:o.literal("comment-delete"),reportHubId:o.number(),commentId:o.number(),clientTempId:o.string()}),Ne=o.object({type:o.literal("report-create"),reportHubId:o.number(),report:Me,clientTempId:o.string(),recipientRawUserId:o.number().optional()}),Ee=o.object({type:o.literal("report-update"),reportHubId:o.number(),report:Me,clientTempId:o.string(),recipientRawUserId:o.number().optional()}),$e=o.object({type:o.literal("report-publish"),reportHubId:o.number(),report:Me,clientTempId:o.string()}),Le=o.object({type:o.literal("report-delete"),reportHubId:o.number(),clientTempId:o.string()}),Fe=o.discriminatedUnion("type",[yt,Se,ve,xe,Ne,Ee,$e,Le]);import{createHash as gt}from"crypto";var Pe=n=>{let t=JSON.stringify(n);return`"${gt("sha256").update(t).digest("hex")}"`};var ft=ne(1,"[Response]"),ae=(n,t,a,s=200,g=ft)=>{let y=Pe(a),O=n.headers.get("If-None-Match");g.info(`[jsonResponseWithETag] ETag: ${y}, If-None-Match: ${O}`);let d=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 t&&d.append("Set-Cookie",t),n.method==="GET"&&s===200&&O===y?new Response(null,{status:304,headers:d}):new Response(JSON.stringify(a),{status:s,headers:d})};import{EventEmitter as bt}from"events";var Ce=(n,t)=>{let[a,s]=n.split("-").map(Number),[g,y]=t.split("-").map(Number);return a!==g?a<g:s<=y},_e=class{constructor(t){this.config=t;this._emitter=new bt;this._state="idle";this._refCount=0;this._lastId="0-0";this._emitter.setMaxListeners(0),this._logger=t.logger??ne(1,"[SSE Reader]")}subscribe(t,a){return this._emitter.on("entry",t),a&&this._emitter.on("error",a),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",t),a&&this._emitter.removeListener("error",a),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 a of t)for(let s of a.messages){this._lastId=s.id;try{let g=s.message?.data?JSON.parse(s.message.data):null,y=g?.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 O=g?.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:s.id,message:s.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=(n,t)=>new Response(JSON.stringify(n),{status:t?.status??200,headers:{"Content-Type":"application/json"}});function ze(n){let{authenticate:t,service:a,encodeUserId:s,redis:g,sseReader:y,streamKey:O}=n,d=n.loginRedirectPath??"/auth/login",W=n.logger??ne(3,"[DailyReportAPI]"),u=n.logger??ne(1,"[DailyReportSSE]"),m=async({request:C})=>{let{user:P,cookie:I}=await t(C,{failureRedirect:d}),L=new Headers;I&&L.append("Set-Cookie",I);let _=null;P&&(_=await a.getUserIdByExternalId(P.id));let w=_?s(_):null;return{data:{user:P,userId:w},headers:L}},E={"business-date":async(C,P,I,L)=>{let _=V(C.searchParams.get("businessDate")),w=C.searchParams.get("forceRefresh")==="true";if(!_)return ae(I,P,{error:{message:"Invalid business date"}},400);let k=await a.getDailyReportsByBusinessDateByExternalId(_,L.id,{forceRefresh:w});return ae(I,P,{businessDate:_,reports:k},200)},ids:async(C,P,I,L)=>{let _=C.searchParams.get("forceRefresh")==="true",w=await a.getDailyReportIdsByExternalId(L.id,{forceRefresh:_});return ae(I,P,{ids:w},200)},report:async(C,P,I,L)=>{let _=C.searchParams.get("reportHubId"),w=C.searchParams.get("forceRefresh")==="true",k=_?Number.parseInt(_,10):NaN;if(!Number.isFinite(k)||k<=0)return ae(I,P,{error:{message:"Invalid reportHubId"}},400);let v=await a.getDailyReportDetailByIdByExternalId(k,L.id,{snapshot:!0,forceRefresh:w});return v?ae(I,P,{report:v},200):ae(I,P,{error:{message:"Report not found"}},404)}};return{index:{loader:m},api:{loader:async({request:C,params:P})=>{let{user:I,cookie:L}=await t(C,{failureRedirect:null}),_=L??null;if(!I)return ae(C,_,{error:{message:"Unauthorized"}},401);if(C.method!=="GET")return ae(C,_,{error:{message:"Method not allowed"}},405);let w=P.endpoint??"",k=E[w];if(!k)return ae(C,_,{error:{message:"Unknown endpoint"}},404);let v=Date.now();try{let D=new URL(C.url);return await k(D,_,C,I)}catch(D){let q=Date.now()-v,j=D instanceof Error?D:new Error(String(D));return W.error(`500 endpoint=${w} elapsed=${q}ms name=${j.name} code=${"code"in j?j.code:"N/A"} message=${j.message}`),W.error("Stack:",j.stack),ae(C,_,{error:{message:"Internal Server Error"}},500)}},action:async({request:C,params:P})=>{let{user:I}=await t(C,{failureRedirect:null});if(!I)return M({error:"Unauthorized"},{status:401});if(P.endpoint!=="action")return M({error:"Unknown endpoint"},{status:404});let _=await a.getUserIdByExternalId(I.id);if(!_)return M({error:"User not found"},{status:404});let w=await C.formData(),k=w.get("intent"),v=w.get("reportHubId"),D=v?Number(v):NaN,q=w.get("businessDate"),j=Number(w.get("operationTimestamp")),x=w.get("clientTempId");if(!x)return M({error:"clientTempId required"},{status:400});if(k!=="create"&&(!D||Number.isNaN(D)))return M({error:"Invalid reportHubId"},{status:400});switch(k){case"create":{if(!q)return M({error:"businessDate required"},{status:400});let c=await a.createDailyReport(_,q,x);return M({status:"OK",intent:"create",report:c,reportHubId:String(c.reportHubId),clientTempId:x})}case"update":{let c=w.get("title"),$=w.get("content");try{return await a.updateDailyReport(D,_,{title:c,content:$},x),M({status:"OK",intent:"update",reportHubId:String(D),clientTempId:x})}catch(A){if(A instanceof Error){if(A.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(A.message==="Not Found")return M({error:"Report not found"},{status:404})}throw A}}case"publish":try{let c=await a.publishDailyReport(D,_,x);return M({status:"OK",intent:"publish",reportHubId:String(D),clientTempId:x,report:c})}catch(c){if(c instanceof Error){if(c.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(c.message==="Not Found")return M({error:"Report not found"},{status:404})}throw c}case"delete":try{return await a.deleteDailyReport(D,_,x),M({status:"OK",intent:"delete",reportHubId:String(D),clientTempId:x})}catch(c){if(c instanceof Error){if(c.message==="Unauthorized")return M({error:"Unauthorized"},{status:403});if(c.message==="Not Found")return M({error:"Report not found"},{status:404})}throw c}case"toggleStar":{let c=w.get("isStarred");if(c===null)return M({error:"isStarred required"},{status:400});let $=c==="true",A=await a.setStarStatus(_,D,q,$,x);return M({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:A.isStarred,isRead:A.isRead},operationTimestamp:j,reportHubId:String(D),clientTempId:x})}case"toggleRead":{let c=w.get("isRead");if(c===null)return M({error:"isRead required"},{status:400});let $=c==="true",A=await a.setReadStatus(_,D,q,$,x);return M({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:A.isStarred,isRead:A.isRead},operationTimestamp:j,reportHubId:String(D),clientTempId:x})}case"addComment":{let c=w.get("content");if(!c)return M({error:"Content required"},{status:400});let $=await a.addComment(_,D,c,q,x),A={...$,userId:$.userId};return M({status:"OK",intent:"addComment",newComment:A,reportHubId:String(D),clientTempId:x})}case"deleteComment":{let c=Number(w.get("commentId"));if(!c||Number.isNaN(c))return M({error:"Invalid commentId"},{status:400});try{return await a.deleteComment(_,D,c,q,x),M({status:"OK",reportHubId:String(D),deletedCommentId:String(c),clientTempId:x})}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 $}}default:return M({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:C,params:P})=>{let{user:I}=await t(C,{failureRedirect:null});if(!I)return new Response("Unauthorized",{status:401});let L=await a.getUserIdByExternalId(I.id);if(!L)return new Response("Forbidden",{status:403});if(P.endpoint!=="updates")return new Response("Not Found",{status:404});let w=new URL(C.url).searchParams.get("lastEventId")||C.headers.get("Last-Event-ID"),k=new TextEncoder,v=null,D=null,q=null,j=!1,x=()=>{if(!j){if(j=!0,D&&(clearInterval(D),D=null),q&&(q(),q=null),v)try{v.desiredSize!==null&&v.close()}catch{}finally{v=null}j=!1}},c=(A,K)=>{if(K.data)try{let T=JSON.parse(K.data),Q=Fe.safeParse(T);if(!Q.success){u.error("SSE message validation failed:",Q.error.format());return}let re=Q.data,de=typeof T.recipientRawUserId=="number"?T.recipientRawUserId:void 0;if(re.type==="status-update"){if(de===void 0||de!==L)return}else if(de!==void 0&&de!==L)return;let ye;if("recipientRawUserId"in T){let{recipientRawUserId:ke,...ge}=T;ye=JSON.stringify(ge)}else ye=K.data;v&&v.desiredSize!==null&&v.enqueue(k.encode(`id: ${A}
2
2
  data: ${ye}
3
3
 
4
4
  `))}catch(T){u.error(`[SSE:${L}] processEntry error:`,T)}},$=new ReadableStream({async start(A){v=A,D=setInterval(()=>{try{v&&v.desiredSize!==null?v.enqueue(k.encode(`: keep-alive
@@ -6,5 +6,5 @@ data: ${ye}
6
6
  `)):x()}catch{x()}},5e3),C.signal.addEventListener("abort",()=>{x()});let K=w||"0-0";if(q=y.subscribe(T=>{Ce(T.id,K)||(K=T.id,c(T.id,T.message))},T=>{u.error(`[SSE:${L}] Fan-Out reader error:`,T),x()}),!w)try{let T=await g?.getClient();if(T){let Q=await T.xRevRange(O,"+","-",{COUNT:1});Q.length>0&&!Ce(Q[0].id,K)&&(K=Q[0].id)}}catch{}if(v&&v.desiredSize!==null){let T=`data: ${JSON.stringify({type:"connected"})}
7
7
 
8
8
  `,Q=K!=="0-0"?`id: ${K}
9
- ${T}`:T;v.enqueue(k.encode(Q))}if(w)try{let T=await g?.getClient();if(T){let Q=await T.xRange(O,w,"+",{COUNT:1e3});for(let re of Q)re.id!==w&&(Ce(re.id,K)||(K=re.id,c(re.id,re.message)))}}catch(T){u.error(`[SSE:${L}] catch-up xRange error:`,T)}},cancel(){x()}});return new Response($,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}}}}import{aliasedTable as Ke,and as G,asc as Je,desc as Ae,eq as p,getColumns as ht,inArray as je,isNull as pe,or as Qe,sql as We}from"drizzle-orm";var se=n=>ht(n);function Xe(n){let{db:t,tables:o,userTable:s,resolveUserId:g,encodeUserId:y,redis:O,cache:d,epochs:W}=n,{hub:u,internal:m,comment:E,label:F,hubLabel:X,userStatus:N}=o,C=n.externalSources??[],P=n.draftLabelName,I=n.logger??ne(1,"[DailyReportService]"),L="daily-report:ids",_=n.idsTtlMs??18e4,w="daily-report:ids:epoch",k="daily-report:business-date:",v=n.businessDateTtlMs??3e5,D="daily-report:date-epoch:",q="daily-report:detail-epoch:",j=n.streamKey??"daily-report:sse-stream",x=n.streamMaxLen??1e4,c=e=>W.incrementEpoch(e),$=async(e,r)=>{let i=await O?.getClient();if(!i){I.warn(`[SSE] Redis client unavailable (${r})`);return}let l=Date.now();try{await i.xAdd(j,"*",{data:JSON.stringify(e)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:x}});let f=Date.now()-l;f>1e3&&I.warn(`[SSE] Slow publish (${r}): ${f}ms`)}catch(f){I.error(`[SSE] Redis publish failed (${r}):`,f)}},A=(e,r)=>{if(!e)return null;let i=e instanceof Date?e:new Date(e);if(Number.isNaN(i.getTime()))return typeof e=="string"?e:null;let l=r==="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(r==="YYYY-MM-DD HH:mm:ss"?i.toLocaleString("ja-JP",l):i.toLocaleDateString("ja-JP",l)).replace(/\//g,"-")},K=e=>e==null||e===""?null:/^\d+$/.test(e)?y(Number(e)):e,T=()=>{let e={};for(let r of C)e[`ext_${r.sourceType}`]=se(r.table);return e},Q=e=>{let r=e;for(let i of C)r=r.leftJoin(i.table,G(p(u.sourceType,i.sourceType),p(u.sourceIdNum,i.idColumn)));return r},re=(e,r)=>{let{hub:i,internal:l}=e,f=i.summary,b=[],h=null,S=null,U=null,z=null,H=null,ee=null,oe=[],J=C.find(R=>R.sourceType===i.sourceType),ce=J?e[`ext_${J.sourceType}`]:void 0;if(J&&ce){let R=J.mapRow(ce);R.content!==void 0&&(f=R.content),R.employeeName!==void 0&&(ee=R.employeeName),R.category!==void 0&&(h=R.category),R.creationCategory!==void 0&&(S=R.creationCategory),R.visitTimeFrom!==void 0&&(U=R.visitTimeFrom),R.visitTimeTo!==void 0&&(z=R.visitTimeTo),R.customerName!==void 0&&(H=R.customerName),R.interviewers!==void 0&&(b=R.interviewers),R.comments!==void 0&&(oe=R.comments)}else i.sourceType==="Internal"&&l&&(f=l.body);let be=e.labels??[],Y=e.comments??[];return{reportHubId:i.id,date:A(i.businessDate,"YYYY-MM-DD"),author:e.creatorName??K(i.createdBy)??"",userId:i.userId?y(i.userId):"",sourceType:i.sourceType??"Internal",createdAt:A(i.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:A(i.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:K(i.updatedBy),employeeName:ee??e.creatorName??K(i.createdBy),category:h,creationCategory:S,visitTimeFrom:U,visitTimeTo:z,customerName:H,interviewers:b,subject:i.title,content:f,comments:oe,isRead:e.isRead??!1,isStarred:e.isStarred??!1,labels:be.map(R=>({id:R.id,name:R.name,color:R.color})),commentItems:Y.map(R=>({...R,userId:y(R.userId),isMine:r?R.userId===r:!1}))}},de=async e=>{let r=Ke(X,"draft_label");return(await t.select({reportHubId:u.id,businessDate:u.businessDate}).from(u).leftJoin(r,G(p(r.hubId,u.id),p(r.labelId,t.select({id:F.id}).top(1).from(F).where(p(F.name,P))))).where(G(pe(u.deletedAt),Qe(p(u.userId,e),pe(r.hubId)))).orderBy(Ae(u.businessDate),Ae(u.id))).map(l=>({...l,businessDate:A(l.businessDate,"YYYY-MM-DD")}))},ye=async e=>(await Q(t.select({hub:se(u),internal:se(m),creatorName:s.displayName,...T()}).from(u)).leftJoin(m,p(u.id,m.hubId)).leftJoin(s,p(u.userId,s.id)).where(G(p(u.businessDate,We`${e}`),pe(u.deletedAt))).orderBy(Ae(u.id))).map(i=>re(i)),ke=e=>`${k}${e}`,ge=new Map,he=async e=>{if(!n.disableUserIdCache&&ge.has(e))return ge.get(e)??null;let r=await g(e);return r!==null&&!n.disableUserIdCache&&ge.set(e,r),r},Ze=async(e,{forceRefresh:r=!1,snapshot:i=!1,ttlMsOverride:l}={})=>{let f=await he(e);if(!f)return[];let b=`${L}:user:${f}`;return d.getOrFetch({cacheKey:b,fetcher:async()=>await de(f),forceRefresh:r,snapshot:i,ttlMsOverride:l??_,epochKey:w})},et=(e,{forceRefresh:r=!1,snapshot:i=!1,ttlMsOverride:l}={})=>{let f=V(e);return f?d.getOrFetch({cacheKey:ke(f),fetcher:()=>ye(f),forceRefresh:r,snapshot:i,ttlMsOverride:l??v}):Promise.resolve([])},Re=null,ue=async()=>{if(Re!==null)return Re;let[e]=await t.select({id:F.id}).top(1).from(F).where(p(F.name,P));return e?(Re=e.id,Re):null},tt=async(e,r,{forceRefresh:i=!1,snapshot:l=!1,ttlMsOverride:f}={})=>{let b=await he(r);if(!b)return[];let h=V(e);if(!h)return[];let S=`daily-report:date:${h}:user:${b}`;return d.getOrFetch({cacheKey:S,fetcher:async()=>{let U=await ue(),z=Ke(X,"draft_label"),H=await Q(t.select({hub:se(u),internal:se(m),isRead:N.isRead,isStarred:N.isStarred,creatorName:s.displayName,...T()}).from(u)).leftJoin(m,p(u.id,m.hubId)).leftJoin(N,G(p(u.id,N.hubId),p(N.userId,b))).leftJoin(z,G(p(z.hubId,u.id),p(z.labelId,U??-1))).leftJoin(s,p(u.userId,s.id)).where(G(p(u.businessDate,We`${h}`),pe(u.deletedAt),Qe(p(u.userId,b),pe(z.hubId)))).orderBy(Ae(u.id));if(H.length===0)return[];let ee=H.map(Y=>Y.hub.id),oe=await t.select({hubId:X.hubId,id:F.id,name:F.name,color:F.color}).from(X).innerJoin(F,p(X.labelId,F.id)).where(je(X.hubId,ee)),J=await t.select({hubId:E.hubId,id:E.id,body:E.body,createdAt:E.createdAt,userId:E.userId,userName:s.displayName}).from(E).leftJoin(s,p(E.userId,s.id)).where(je(E.hubId,ee)).orderBy(Je(E.createdAt)),ce=new Map,be=new Map;for(let Y of oe){let R=ce.get(Y.hubId);R||(R=[],ce.set(Y.hubId,R)),R.push({id:Y.id,name:Y.name,color:Y.color})}for(let Y of J){let R=be.get(Y.hubId);R||(R=[],be.set(Y.hubId,R)),R.push({id:Y.id,content:Y.body,createdAt:A(Y.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:Y.userId,userName:Y.userName||""})}return H.map(Y=>{let R=Y.hub.id;return re({...Y,labels:ce.get(R)||[],comments:be.get(R)||[]},b)})},forceRefresh:i,snapshot:l,ttlMsOverride:f??v,epochKey:`${D}${h}`})},fe=async(e,r,{forceRefresh:i=!1,snapshot:l=!1,ttlMsOverride:f}={})=>{let b=`daily-report:detail:${e}:user:${r}`;return(await d.getOrFetch({cacheKey:b,fetcher:async()=>{let S=await Q(t.select({hub:se(u),internal:se(m),isRead:N.isRead,isStarred:N.isStarred,creatorName:s.displayName,...T()}).from(u)).leftJoin(m,p(u.id,m.hubId)).leftJoin(N,G(p(u.id,N.hubId),p(N.userId,r))).leftJoin(s,p(u.userId,s.id)).where(G(p(u.id,e),pe(u.deletedAt)));if(S.length===0)return[];let U=S[0].hub.id,z=await t.select({id:F.id,name:F.name,color:F.color}).from(X).innerJoin(F,p(X.labelId,F.id)).where(p(X.hubId,U)),H=await t.select({id:E.id,body:E.body,createdAt:E.createdAt,userId:E.userId,userName:s.displayName}).from(E).leftJoin(s,p(E.userId,s.id)).where(p(E.hubId,U)).orderBy(Je(E.createdAt)),ee=z.map(J=>({id:J.id,name:J.name,color:J.color})),oe=H.map(J=>({id:J.id,content:J.body,createdAt:A(J.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:J.userId,userName:J.userName||""}));return[re({...S[0],labels:ee,comments:oe},r)]},forceRefresh:i,snapshot:l,ttlMsOverride:f??v,epochKey:`${q}${e}`}))[0]??null},rt=async(e,r,i={})=>{let l=await he(r);return l?fe(e,l,i):null},nt=async(e,r,i,l,f)=>{let b=await t.select().top(1).from(N).where(G(p(N.hubId,r),p(N.userId,e))),h;if(b.length>0?b[0].isStarred!==l?h=(await t.update(N).set({isStarred:l,updatedAt:new Date,updatedBy:String(e)}).output().where(G(p(N.hubId,r),p(N.userId,e))))[0]:h=b[0]:h=(await t.insert(N).output().values({hubId:r,userId:e,isStarred:l,isRead:!1,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}))[0],i){let S=V(i);S&&(d.invalidate(`daily-report:date:${S}:user:${e}`),await c(`${D}${S}`))}return d.invalidate(`daily-report:detail:${r}`),d.invalidate(`daily-report:detail:${r}:user:${e}`),await c(`${q}${r}`),await $(Se.parse({type:"status-update",reportHubId:r,recipientRawUserId:e,statusType:"star",value:l,clientTempId:f}),"setStarStatus"),h},at=async(e,r,i,l,f)=>{let b=await t.select().top(1).from(N).where(G(p(N.hubId,r),p(N.userId,e))),h;if(b.length>0?b[0].isRead!==l?h=(await t.update(N).set({isRead:l,updatedAt:new Date,updatedBy:String(e)}).output().where(G(p(N.hubId,r),p(N.userId,e))))[0]:h=b[0]:h=(await t.insert(N).output().values({hubId:r,userId:e,isRead:l,isStarred:!1,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}))[0],i){let S=V(i);S&&(d.invalidate(`daily-report:date:${S}:user:${e}`),await c(`${D}${S}`))}return d.invalidate(`daily-report:detail:${r}`),d.invalidate(`daily-report:detail:${r}:user:${e}`),await c(`${q}${r}`),await $(Se.parse({type:"status-update",reportHubId:r,recipientRawUserId:e,statusType:"read",value:l,clientTempId:f}),"setReadStatus"),h},ot=async(e,r,i,l,f)=>{let[b]=await t.insert(E).output().values({hubId:r,userId:e,body:i,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}),[h]=await t.select({displayName:s.displayName}).top(1).from(s).where(p(s.id,e)),S=h?.displayName??"Unknown";if(l){let z=V(l);z&&(d.invalidatePrefix(`daily-report:date:${z}:user:`),await c(`${D}${z}`))}d.invalidate(`daily-report:detail:${r}`),d.invalidatePrefix(`daily-report:detail:${r}:user:`),await c(`${q}${r}`);let U={id:b.id,userId:y(b.userId),userName:S,content:b.body,createdAt:A(b.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await $(ve.parse({type:"comment-add",reportHubId:r,comment:U,clientTempId:f}),"addComment"),U},it=async(e,r)=>await e.select().top(1).from(E).where(p(E.id,r)),st=async(e,r,i,l,f)=>{let b=await it(t,i);if(b.length===0)throw new Error("Not Found");if(b[0].userId!==e)throw new Error("Unauthorized");if(await t.delete(E).where(p(E.id,i)),l){let h=V(l);h&&(d.invalidatePrefix(`daily-report:date:${h}:user:`),await c(`${D}${h}`))}d.invalidate(`daily-report:detail:${r}`),d.invalidatePrefix(`daily-report:detail:${r}:user:`),await c(`${q}${r}`),await $(xe.parse({type:"comment-delete",reportHubId:r,commentId:i,clientTempId:f}),"deleteComment")},lt=async(e,r,i)=>{I.info("createDailyReport called",{userId:e,businessDate:r});let[l]=await t.select({displayName:s.displayName}).from(s).where(p(s.id,e)),f=l?.displayName??y(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(u).output().values({sourceType:"Internal",sourceId:z,businessDate:new Date(r),userId:e,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)});await U.update(u).set({sourceId:String(H.id)}).where(p(u.id,H.id)),I.info("Hub created",H),await U.insert(m).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 ee=await ue();I.info("draftLabelId",ee);let oe=[];return ee&&(await U.insert(X).values({hubId:H.id,labelId:ee,createdAt:new Date,createdBy:String(e)}),oe.push({id:ee,name:P,color:null})),I.info("Label assigned"),{reportHubId:H.id,date:r,createdAt:A(H.createdAt,"YYYY-MM-DD HH:mm:ss"),author:f,userId:y(e),sourceType:"Internal",employeeName:f,updatedBy:y(e),updatedAt:A(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:oe,commentItems:[]}}),h=V(r);h&&d.invalidate(`daily-report:date:${h}:user:${e}`),d.invalidatePrefix(k),d.invalidate(`${L}:user:${e}`),await c(w),h&&await c(`${D}${h}`);let S=await fe(b.reportHubId,e,{forceRefresh:!0});if(S){let U=await ue(),z=U?S.labels.some(H=>H.id===U):!1;await $(Ne.parse({type:"report-create",reportHubId:S.reportHubId,report:S,clientTempId:i,recipientRawUserId:z?e:void 0}),"createDailyReport")}return S??b}catch(b){throw I.error("Error in createDailyReport",b),b}},De=async(e,r)=>await e.select().top(1).from(u).where(p(u.id,r)),Te=async(e,r,i)=>{await e.update(u).set(i).where(p(u.id,r))},Be=async(e,r,i)=>{await e.update(m).set(i).where(p(m.hubId,r))},Ue=async(e,r,i)=>{await e.delete(X).where(G(p(X.hubId,r),p(X.labelId,i)))};return{streamKey:j,streamMaxLen:x,getUserIdByExternalId:he,getDailyReportIdsByExternalId:Ze,getDailyReportsByBusinessDate:et,getDailyReportsByBusinessDateByExternalId:tt,getDailyReportDetailById:fe,getDailyReportDetailByIdByExternalId:rt,getDraftLabelId:ue,setStarStatus:nt,setReadStatus:at,addComment:ot,deleteComment:st,createDailyReport:lt,updateDailyReport:async(e,r,i,l)=>{let f=await De(t,e);if(!f.length||f[0].deletedAt)throw new Error("Not Found");if(f[0].userId!==r)throw new Error("Unauthorized");await t.transaction(async h=>{i.title!==void 0&&await Te(h,e,{title:i.title,updatedAt:new Date,updatedBy:String(r)}),i.content!==void 0&&await Be(h,e,{body:i.content,updatedAt:new Date,updatedBy:String(r)})}),d.invalidatePrefix(`daily-report:detail:${e}:user:`),d.invalidatePrefix(k);let b=await fe(e,r,{forceRefresh:!0});if(b){let h=await ue(),S=h?b.labels.some(U=>U.id===h):!1;await $(Ee.parse({type:"report-update",reportHubId:b.reportHubId,report:b,clientTempId:l,recipientRawUserId:S?r:void 0}),"updateDailyReport")}},publishDailyReport:async(e,r,i)=>{let l=await De(t,e);if(!l.length)throw new Error("Not Found");if(l[0].userId!==r)throw new Error("Unauthorized");let f=await ue();if(!f)return null;if(await Ue(t,e,f),d.invalidatePrefix(`daily-report:detail:${e}:user:`),d.invalidatePrefix(k),d.invalidatePrefix(L),await c(w),l[0].businessDate){let S=V(A(l[0].businessDate,"YYYY-MM-DD"));S&&await c(`${D}${S}`)}let b=V(A(l[0].businessDate,"YYYY-MM-DD"));b&&d.invalidate(`daily-report:date:${b}:user:${r}`);let h=await fe(e,r,{forceRefresh:!0});return h&&await $($e.parse({type:"report-publish",reportHubId:h.reportHubId,report:h,clientTempId:i}),"publishDailyReport"),h??null},deleteDailyReport:async(e,r,i)=>{let l=await De(t,e);if(!l.length||l[0].deletedAt)throw new Error("Not Found");if(l[0].userId!==r)throw new Error("Unauthorized");if(await Te(t,e,{deletedAt:new Date,deletedBy:String(r),updatedAt:new Date,updatedBy:String(r)}),d.invalidatePrefix(`daily-report:detail:${e}:user:`),d.invalidatePrefix(k),d.invalidatePrefix(L),await c(w),l[0].businessDate){let f=V(A(l[0].businessDate,"YYYY-MM-DD"));f&&await c(`${D}${f}`)}await $(Le.parse({type:"report-delete",reportHubId:e,clientTempId:i}),"deleteDailyReport")},findDailyReportHubById:De,updateDailyReportHub:Te,updateDailyReportInternal:Be,deleteDailyReportLabel:Ue}}var Rt=ne(1,"[DailyReportExternalSource]"),Vt=(n,t,o,s=Rt)=>{if(!n)return[];try{let g=JSON.parse(n);return Array.isArray(g)?g.map(o).filter(y=>y!==null):(s.warn(`Unexpected ${t} format: not an array`),[])}catch(g){return s.warn(`Failed to parse ${t}:`,g),[]}};import{desc as Ge,sql as Dt}from"drizzle-orm";import{bigint as Z,bit as Ve,date as wt,datetime2 as te,foreignKey as ie,index as le,int as St,mssqlSchema as It,nvarchar as B,primaryKey as me}from"drizzle-orm/mssql-core";function rr(n,t){let o=It(n),s=t.userTable,g=o.table("DailyReportHub",{id:Z("id",{mode:"number"}).identity().notNull(),sourceType:B("source_type",{length:20}).notNull(),sourceId:B("source_id",{length:100}).notNull(),sourceIdNum:Z("source_id_num",{mode:"number"}).generatedAlwaysAs(Dt`TRY_CAST(source_id AS BIGINT)`),businessDate:wt("business_date"),userId:Z("user_id",{mode:"number"}),title:B("title",{length:200}),summary:B("summary",{length:"max"}),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull(),deletedAt:te("deleted_at"),deletedBy:B("deleted_by",{length:50})},m=>[me({name:`${n}_DailyReportHub_pk`,columns:[m.id]}),ie({name:`${n}_DailyReportHub_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]}),le(`${n}_DailyReportHub_business_date_index`).on(m.businessDate),le(`${n}_DailyReportHub_updated_at_index`).on(m.updatedAt),le(`${n}_DailyReportHub_source_index`).on(m.sourceType,m.sourceId),le(`${n}_DailyReportHub_user_id_index`).on(m.userId),le(`${n}_DailyReportHub_business_date_id_index`).on(Ge(m.businessDate),Ge(m.id)),le(`${n}_DailyReportHub_deleted_at_index`).on(m.deletedAt)]),y=o.table("DailyReportInternal",{hubId:Z("hub_id",{mode:"number"}).notNull(),body:B("body",{length:"max"}),metadata:B("metadata",{length:"max"}),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportInternal_pk`,columns:[m.hubId]}),ie({name:`${n}_DailyReportInternal_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]})]),O=o.table("DailyReportComment",{id:Z("id",{mode:"number"}).identity().notNull(),hubId:Z("hub_id",{mode:"number"}).notNull(),userId:Z("user_id",{mode:"number"}).notNull(),body:B("body",{length:"max"}).notNull(),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportComment_pk`,columns:[m.id]}),ie({name:`${n}_DailyReportComment_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]}),ie({name:`${n}_DailyReportComment_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]}),le(`${n}_DailyReportComment_hub_id_index`).on(m.hubId)]),d=o.table("DailyReportLabel",{id:Z("id",{mode:"number"}).identity().notNull(),userId:Z("user_id",{mode:"number"}),name:B("name",{length:50}).notNull(),color:B("color",{length:20}),sortOrder:St("sort_order"),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportLabel_pk`,columns:[m.id]}),ie({name:`${n}_DailyReportLabel_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]})]),W=o.table("DailyReportHub_Label",{hubId:Z("hub_id",{mode:"number"}).notNull(),labelId:Z("label_id",{mode:"number"}).notNull(),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportHub_Label_pk`,columns:[m.hubId,m.labelId]}),ie({name:`${n}_DailyReportHub_Label_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]}),ie({name:`${n}_DailyReportHub_Label_label_id_fk`,columns:[m.labelId],foreignColumns:[d.id]})]),u=o.table("DailyReportUserStatus",{hubId:Z("hub_id",{mode:"number"}).notNull(),userId:Z("user_id",{mode:"number"}).notNull(),isRead:Ve("is_read").default(!1).notNull(),isStarred:Ve("is_starred").default(!1).notNull(),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportUserStatus_pk`,columns:[m.hubId,m.userId]}),ie({name:`${n}_DailyReportUserStatus_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]}),ie({name:`${n}_DailyReportUserStatus_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]})]);return{hub:g,internal:y,comment:O,label:d,hubLabel:W,userStatus:u}}function lr(n){let t=He(n.redis),o=new we({defaultTtlMs:n.cacheDefaultTtlMs??6e4},t),s=Xe({...n,cache:o,epochs:t}),g=new _e({redis:n.redis,streamKey:s.streamKey,cache:o,logger:n.logger}),y=ze({authenticate:n.authenticate,service:s,encodeUserId:n.encodeUserId,redis:n.redis,sseReader:g,streamKey:s.streamKey,loginRedirectPath:n.loginRedirectPath,logger:n.logger});return{service:s,cache:o,epochs:t,sseReader:g,streamKey:s.streamKey,...y}}export{_e as DailyReportSseReader,we as SqlResultCache,ze as createDailyReportHandlers,lr as createDailyReportServer,Xe as createDailyReportService,He as createEpochStore,rr as defineDailyReportSchema,Pe as generateETag,Ce as isStreamIdLte,ae as jsonResponseWithETag,Vt as transformJsonArray};
9
+ ${T}`:T;v.enqueue(k.encode(Q))}if(w)try{let T=await g?.getClient();if(T){let Q=await T.xRange(O,w,"+",{COUNT:1e3});for(let re of Q)re.id!==w&&(Ce(re.id,K)||(K=re.id,c(re.id,re.message)))}}catch(T){u.error(`[SSE:${L}] catch-up xRange error:`,T)}},cancel(){x()}});return new Response($,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}}}}import{aliasedTable as Ke,and as G,asc as Je,desc as Ae,eq as p,getColumns as ht,inArray as je,isNull as pe,or as Qe,sql as We}from"drizzle-orm";var se=n=>ht(n);function Xe(n){let{db:t,tables:a,userTable:s,resolveUserId:g,encodeUserId:y,redis:O,cache:d,epochs:W}=n,{hub:u,internal:m,comment:E,label:F,hubLabel:X,userStatus:N}=a,C=n.externalSources??[],P=n.draftLabelName,I=n.logger??ne(1,"[DailyReportService]"),L="daily-report:ids",_=n.idsTtlMs??18e4,w="daily-report:ids:epoch",k="daily-report:business-date:",v=n.businessDateTtlMs??3e5,D="daily-report:date-epoch:",q="daily-report:detail-epoch:",j=n.streamKey??"daily-report:sse-stream",x=n.streamMaxLen??1e4,c=e=>W.incrementEpoch(e),$=async(e,r)=>{let i=await O?.getClient();if(!i){I.warn(`[SSE] Redis client unavailable (${r})`);return}let l=Date.now();try{await i.xAdd(j,"*",{data:JSON.stringify(e)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:x}});let f=Date.now()-l;f>1e3&&I.warn(`[SSE] Slow publish (${r}): ${f}ms`)}catch(f){I.error(`[SSE] Redis publish failed (${r}):`,f)}},A=(e,r)=>{if(!e)return null;let i=e instanceof Date?e:new Date(e);if(Number.isNaN(i.getTime()))return typeof e=="string"?e:null;let l=r==="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(r==="YYYY-MM-DD HH:mm:ss"?i.toLocaleString("ja-JP",l):i.toLocaleDateString("ja-JP",l)).replace(/\//g,"-")},K=e=>e==null||e===""?null:/^\d+$/.test(e)?y(Number(e)):e,T=()=>{let e={};for(let r of C)e[`ext_${r.sourceType}`]=se(r.table);return e},Q=e=>{let r=e;for(let i of C)r=r.leftJoin(i.table,G(p(u.sourceType,i.sourceType),p(u.sourceIdNum,i.idColumn)));return r},re=(e,r)=>{let{hub:i,internal:l}=e,f=i.summary,b=[],h=null,S=null,U=null,z=null,H=null,ee=null,oe=[],J=C.find(R=>R.sourceType===i.sourceType),ce=J?e[`ext_${J.sourceType}`]:void 0;if(J&&ce){let R=J.mapRow(ce);R.content!==void 0&&(f=R.content),R.employeeName!==void 0&&(ee=R.employeeName),R.category!==void 0&&(h=R.category),R.creationCategory!==void 0&&(S=R.creationCategory),R.visitTimeFrom!==void 0&&(U=R.visitTimeFrom),R.visitTimeTo!==void 0&&(z=R.visitTimeTo),R.customerName!==void 0&&(H=R.customerName),R.interviewers!==void 0&&(b=R.interviewers),R.comments!==void 0&&(oe=R.comments)}else i.sourceType==="Internal"&&l&&(f=l.body);let be=e.labels??[],Y=e.comments??[];return{reportHubId:i.id,date:A(i.businessDate,"YYYY-MM-DD"),author:e.creatorName??K(i.createdBy)??"",userId:i.userId?y(i.userId):"",createdAt:A(i.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:A(i.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:K(i.updatedBy),employeeName:ee??e.creatorName??K(i.createdBy),category:h,creationCategory:S,visitTimeFrom:U,visitTimeTo:z,customerName:H,interviewers:b,subject:i.title,content:f,comments:oe,isRead:e.isRead??!1,isStarred:e.isStarred??!1,labels:be.map(R=>({id:R.id,name:R.name,color:R.color})),commentItems:Y.map(R=>({...R,userId:y(R.userId),isMine:r?R.userId===r:!1}))}},de=async e=>{let r=Ke(X,"draft_label");return(await t.select({reportHubId:u.id,businessDate:u.businessDate}).from(u).leftJoin(r,G(p(r.hubId,u.id),p(r.labelId,t.select({id:F.id}).top(1).from(F).where(p(F.name,P))))).where(G(pe(u.deletedAt),Qe(p(u.userId,e),pe(r.hubId)))).orderBy(Ae(u.businessDate),Ae(u.id))).map(l=>({...l,businessDate:A(l.businessDate,"YYYY-MM-DD")}))},ye=async e=>(await Q(t.select({hub:se(u),internal:se(m),creatorName:s.displayName,...T()}).from(u)).leftJoin(m,p(u.id,m.hubId)).leftJoin(s,p(u.userId,s.id)).where(G(p(u.businessDate,We`${e}`),pe(u.deletedAt))).orderBy(Ae(u.id))).map(i=>re(i)),ke=e=>`${k}${e}`,ge=new Map,he=async e=>{if(!n.disableUserIdCache&&ge.has(e))return ge.get(e)??null;let r=await g(e);return r!==null&&!n.disableUserIdCache&&ge.set(e,r),r},Ze=async(e,{forceRefresh:r=!1,snapshot:i=!1,ttlMsOverride:l}={})=>{let f=await he(e);if(!f)return[];let b=`${L}:user:${f}`;return d.getOrFetch({cacheKey:b,fetcher:async()=>await de(f),forceRefresh:r,snapshot:i,ttlMsOverride:l??_,epochKey:w})},et=(e,{forceRefresh:r=!1,snapshot:i=!1,ttlMsOverride:l}={})=>{let f=V(e);return f?d.getOrFetch({cacheKey:ke(f),fetcher:()=>ye(f),forceRefresh:r,snapshot:i,ttlMsOverride:l??v}):Promise.resolve([])},Re=null,ue=async()=>{if(Re!==null)return Re;let[e]=await t.select({id:F.id}).top(1).from(F).where(p(F.name,P));return e?(Re=e.id,Re):null},tt=async(e,r,{forceRefresh:i=!1,snapshot:l=!1,ttlMsOverride:f}={})=>{let b=await he(r);if(!b)return[];let h=V(e);if(!h)return[];let S=`daily-report:date:${h}:user:${b}`;return d.getOrFetch({cacheKey:S,fetcher:async()=>{let U=await ue(),z=Ke(X,"draft_label"),H=await Q(t.select({hub:se(u),internal:se(m),isRead:N.isRead,isStarred:N.isStarred,creatorName:s.displayName,...T()}).from(u)).leftJoin(m,p(u.id,m.hubId)).leftJoin(N,G(p(u.id,N.hubId),p(N.userId,b))).leftJoin(z,G(p(z.hubId,u.id),p(z.labelId,U??-1))).leftJoin(s,p(u.userId,s.id)).where(G(p(u.businessDate,We`${h}`),pe(u.deletedAt),Qe(p(u.userId,b),pe(z.hubId)))).orderBy(Ae(u.id));if(H.length===0)return[];let ee=H.map(Y=>Y.hub.id),oe=await t.select({hubId:X.hubId,id:F.id,name:F.name,color:F.color}).from(X).innerJoin(F,p(X.labelId,F.id)).where(je(X.hubId,ee)),J=await t.select({hubId:E.hubId,id:E.id,body:E.body,createdAt:E.createdAt,userId:E.userId,userName:s.displayName}).from(E).leftJoin(s,p(E.userId,s.id)).where(je(E.hubId,ee)).orderBy(Je(E.createdAt)),ce=new Map,be=new Map;for(let Y of oe){let R=ce.get(Y.hubId);R||(R=[],ce.set(Y.hubId,R)),R.push({id:Y.id,name:Y.name,color:Y.color})}for(let Y of J){let R=be.get(Y.hubId);R||(R=[],be.set(Y.hubId,R)),R.push({id:Y.id,content:Y.body,createdAt:A(Y.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:Y.userId,userName:Y.userName||""})}return H.map(Y=>{let R=Y.hub.id;return re({...Y,labels:ce.get(R)||[],comments:be.get(R)||[]},b)})},forceRefresh:i,snapshot:l,ttlMsOverride:f??v,epochKey:`${D}${h}`})},fe=async(e,r,{forceRefresh:i=!1,snapshot:l=!1,ttlMsOverride:f}={})=>{let b=`daily-report:detail:${e}:user:${r}`;return(await d.getOrFetch({cacheKey:b,fetcher:async()=>{let S=await Q(t.select({hub:se(u),internal:se(m),isRead:N.isRead,isStarred:N.isStarred,creatorName:s.displayName,...T()}).from(u)).leftJoin(m,p(u.id,m.hubId)).leftJoin(N,G(p(u.id,N.hubId),p(N.userId,r))).leftJoin(s,p(u.userId,s.id)).where(G(p(u.id,e),pe(u.deletedAt)));if(S.length===0)return[];let U=S[0].hub.id,z=await t.select({id:F.id,name:F.name,color:F.color}).from(X).innerJoin(F,p(X.labelId,F.id)).where(p(X.hubId,U)),H=await t.select({id:E.id,body:E.body,createdAt:E.createdAt,userId:E.userId,userName:s.displayName}).from(E).leftJoin(s,p(E.userId,s.id)).where(p(E.hubId,U)).orderBy(Je(E.createdAt)),ee=z.map(J=>({id:J.id,name:J.name,color:J.color})),oe=H.map(J=>({id:J.id,content:J.body,createdAt:A(J.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:J.userId,userName:J.userName||""}));return[re({...S[0],labels:ee,comments:oe},r)]},forceRefresh:i,snapshot:l,ttlMsOverride:f??v,epochKey:`${q}${e}`}))[0]??null},rt=async(e,r,i={})=>{let l=await he(r);return l?fe(e,l,i):null},nt=async(e,r,i,l,f)=>{let b=await t.select().top(1).from(N).where(G(p(N.hubId,r),p(N.userId,e))),h;if(b.length>0?b[0].isStarred!==l?h=(await t.update(N).set({isStarred:l,updatedAt:new Date,updatedBy:String(e)}).output().where(G(p(N.hubId,r),p(N.userId,e))))[0]:h=b[0]:h=(await t.insert(N).output().values({hubId:r,userId:e,isStarred:l,isRead:!1,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}))[0],i){let S=V(i);S&&(d.invalidate(`daily-report:date:${S}:user:${e}`),await c(`${D}${S}`))}return d.invalidate(`daily-report:detail:${r}`),d.invalidate(`daily-report:detail:${r}:user:${e}`),await c(`${q}${r}`),await $(Se.parse({type:"status-update",reportHubId:r,recipientRawUserId:e,statusType:"star",value:l,clientTempId:f}),"setStarStatus"),h},at=async(e,r,i,l,f)=>{let b=await t.select().top(1).from(N).where(G(p(N.hubId,r),p(N.userId,e))),h;if(b.length>0?b[0].isRead!==l?h=(await t.update(N).set({isRead:l,updatedAt:new Date,updatedBy:String(e)}).output().where(G(p(N.hubId,r),p(N.userId,e))))[0]:h=b[0]:h=(await t.insert(N).output().values({hubId:r,userId:e,isRead:l,isStarred:!1,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}))[0],i){let S=V(i);S&&(d.invalidate(`daily-report:date:${S}:user:${e}`),await c(`${D}${S}`))}return d.invalidate(`daily-report:detail:${r}`),d.invalidate(`daily-report:detail:${r}:user:${e}`),await c(`${q}${r}`),await $(Se.parse({type:"status-update",reportHubId:r,recipientRawUserId:e,statusType:"read",value:l,clientTempId:f}),"setReadStatus"),h},ot=async(e,r,i,l,f)=>{let[b]=await t.insert(E).output().values({hubId:r,userId:e,body:i,createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)}),[h]=await t.select({displayName:s.displayName}).top(1).from(s).where(p(s.id,e)),S=h?.displayName??"Unknown";if(l){let z=V(l);z&&(d.invalidatePrefix(`daily-report:date:${z}:user:`),await c(`${D}${z}`))}d.invalidate(`daily-report:detail:${r}`),d.invalidatePrefix(`daily-report:detail:${r}:user:`),await c(`${q}${r}`);let U={id:b.id,userId:y(b.userId),userName:S,content:b.body,createdAt:A(b.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await $(ve.parse({type:"comment-add",reportHubId:r,comment:U,clientTempId:f}),"addComment"),U},it=async(e,r)=>await e.select().top(1).from(E).where(p(E.id,r)),st=async(e,r,i,l,f)=>{let b=await it(t,i);if(b.length===0)throw new Error("Not Found");if(b[0].userId!==e)throw new Error("Unauthorized");if(await t.delete(E).where(p(E.id,i)),l){let h=V(l);h&&(d.invalidatePrefix(`daily-report:date:${h}:user:`),await c(`${D}${h}`))}d.invalidate(`daily-report:detail:${r}`),d.invalidatePrefix(`daily-report:detail:${r}:user:`),await c(`${q}${r}`),await $(xe.parse({type:"comment-delete",reportHubId:r,commentId:i,clientTempId:f}),"deleteComment")},lt=async(e,r,i)=>{I.info("createDailyReport called",{userId:e,businessDate:r});let[l]=await t.select({displayName:s.displayName}).from(s).where(p(s.id,e)),f=l?.displayName??y(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(u).output().values({sourceType:"Internal",sourceId:z,businessDate:new Date(r),userId:e,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(e),updatedAt:new Date,updatedBy:String(e)});await U.update(u).set({sourceId:String(H.id)}).where(p(u.id,H.id)),I.info("Hub created",H),await U.insert(m).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 ee=await ue();I.info("draftLabelId",ee);let oe=[];return ee&&(await U.insert(X).values({hubId:H.id,labelId:ee,createdAt:new Date,createdBy:String(e)}),oe.push({id:ee,name:P,color:null})),I.info("Label assigned"),{reportHubId:H.id,date:r,createdAt:A(H.createdAt,"YYYY-MM-DD HH:mm:ss"),author:f,userId:y(e),employeeName:f,updatedBy:y(e),updatedAt:A(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:oe,commentItems:[]}}),h=V(r);h&&d.invalidate(`daily-report:date:${h}:user:${e}`),d.invalidatePrefix(k),d.invalidate(`${L}:user:${e}`),await c(w),h&&await c(`${D}${h}`);let S=await fe(b.reportHubId,e,{forceRefresh:!0});if(S){let U=await ue(),z=U?S.labels.some(H=>H.id===U):!1;await $(Ne.parse({type:"report-create",reportHubId:S.reportHubId,report:S,clientTempId:i,recipientRawUserId:z?e:void 0}),"createDailyReport")}return S??b}catch(b){throw I.error("Error in createDailyReport",b),b}},De=async(e,r)=>await e.select().top(1).from(u).where(p(u.id,r)),Te=async(e,r,i)=>{await e.update(u).set(i).where(p(u.id,r))},Be=async(e,r,i)=>{await e.update(m).set(i).where(p(m.hubId,r))},Ue=async(e,r,i)=>{await e.delete(X).where(G(p(X.hubId,r),p(X.labelId,i)))};return{streamKey:j,streamMaxLen:x,getUserIdByExternalId:he,getDailyReportIdsByExternalId:Ze,getDailyReportsByBusinessDate:et,getDailyReportsByBusinessDateByExternalId:tt,getDailyReportDetailById:fe,getDailyReportDetailByIdByExternalId:rt,getDraftLabelId:ue,setStarStatus:nt,setReadStatus:at,addComment:ot,deleteComment:st,createDailyReport:lt,updateDailyReport:async(e,r,i,l)=>{let f=await De(t,e);if(!f.length||f[0].deletedAt)throw new Error("Not Found");if(f[0].userId!==r)throw new Error("Unauthorized");await t.transaction(async h=>{i.title!==void 0&&await Te(h,e,{title:i.title,updatedAt:new Date,updatedBy:String(r)}),i.content!==void 0&&await Be(h,e,{body:i.content,updatedAt:new Date,updatedBy:String(r)})}),d.invalidatePrefix(`daily-report:detail:${e}:user:`),d.invalidatePrefix(k);let b=await fe(e,r,{forceRefresh:!0});if(b){let h=await ue(),S=h?b.labels.some(U=>U.id===h):!1;await $(Ee.parse({type:"report-update",reportHubId:b.reportHubId,report:b,clientTempId:l,recipientRawUserId:S?r:void 0}),"updateDailyReport")}},publishDailyReport:async(e,r,i)=>{let l=await De(t,e);if(!l.length)throw new Error("Not Found");if(l[0].userId!==r)throw new Error("Unauthorized");let f=await ue();if(!f)return null;if(await Ue(t,e,f),d.invalidatePrefix(`daily-report:detail:${e}:user:`),d.invalidatePrefix(k),d.invalidatePrefix(L),await c(w),l[0].businessDate){let S=V(A(l[0].businessDate,"YYYY-MM-DD"));S&&await c(`${D}${S}`)}let b=V(A(l[0].businessDate,"YYYY-MM-DD"));b&&d.invalidate(`daily-report:date:${b}:user:${r}`);let h=await fe(e,r,{forceRefresh:!0});return h&&await $($e.parse({type:"report-publish",reportHubId:h.reportHubId,report:h,clientTempId:i}),"publishDailyReport"),h??null},deleteDailyReport:async(e,r,i)=>{let l=await De(t,e);if(!l.length||l[0].deletedAt)throw new Error("Not Found");if(l[0].userId!==r)throw new Error("Unauthorized");if(await Te(t,e,{deletedAt:new Date,deletedBy:String(r),updatedAt:new Date,updatedBy:String(r)}),d.invalidatePrefix(`daily-report:detail:${e}:user:`),d.invalidatePrefix(k),d.invalidatePrefix(L),await c(w),l[0].businessDate){let f=V(A(l[0].businessDate,"YYYY-MM-DD"));f&&await c(`${D}${f}`)}await $(Le.parse({type:"report-delete",reportHubId:e,clientTempId:i}),"deleteDailyReport")},findDailyReportHubById:De,updateDailyReportHub:Te,updateDailyReportInternal:Be,deleteDailyReportLabel:Ue}}var Rt=ne(1,"[DailyReportExternalSource]"),Vt=(n,t,a,s=Rt)=>{if(!n)return[];try{let g=JSON.parse(n);return Array.isArray(g)?g.map(a).filter(y=>y!==null):(s.warn(`Unexpected ${t} format: not an array`),[])}catch(g){return s.warn(`Failed to parse ${t}:`,g),[]}};import{desc as Ge,sql as Dt}from"drizzle-orm";import{bigint as Z,bit as Ve,date as wt,datetime2 as te,foreignKey as ie,index as le,int as St,mssqlSchema as It,nvarchar as B,primaryKey as me}from"drizzle-orm/mssql-core";function rr(n,t){let a=It(n),s=t.userTable,g=a.table("DailyReportHub",{id:Z("id",{mode:"number"}).identity().notNull(),sourceType:B("source_type",{length:20}).notNull(),sourceId:B("source_id",{length:100}).notNull(),sourceIdNum:Z("source_id_num",{mode:"number"}).generatedAlwaysAs(Dt`TRY_CAST(source_id AS BIGINT)`),businessDate:wt("business_date"),userId:Z("user_id",{mode:"number"}),title:B("title",{length:200}),summary:B("summary",{length:"max"}),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull(),deletedAt:te("deleted_at"),deletedBy:B("deleted_by",{length:50})},m=>[me({name:`${n}_DailyReportHub_pk`,columns:[m.id]}),ie({name:`${n}_DailyReportHub_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]}),le(`${n}_DailyReportHub_business_date_index`).on(m.businessDate),le(`${n}_DailyReportHub_updated_at_index`).on(m.updatedAt),le(`${n}_DailyReportHub_source_index`).on(m.sourceType,m.sourceId),le(`${n}_DailyReportHub_user_id_index`).on(m.userId),le(`${n}_DailyReportHub_business_date_id_index`).on(Ge(m.businessDate),Ge(m.id)),le(`${n}_DailyReportHub_deleted_at_index`).on(m.deletedAt)]),y=a.table("DailyReportInternal",{hubId:Z("hub_id",{mode:"number"}).notNull(),body:B("body",{length:"max"}),metadata:B("metadata",{length:"max"}),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportInternal_pk`,columns:[m.hubId]}),ie({name:`${n}_DailyReportInternal_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]})]),O=a.table("DailyReportComment",{id:Z("id",{mode:"number"}).identity().notNull(),hubId:Z("hub_id",{mode:"number"}).notNull(),userId:Z("user_id",{mode:"number"}).notNull(),body:B("body",{length:"max"}).notNull(),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportComment_pk`,columns:[m.id]}),ie({name:`${n}_DailyReportComment_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]}),ie({name:`${n}_DailyReportComment_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]}),le(`${n}_DailyReportComment_hub_id_index`).on(m.hubId)]),d=a.table("DailyReportLabel",{id:Z("id",{mode:"number"}).identity().notNull(),userId:Z("user_id",{mode:"number"}),name:B("name",{length:50}).notNull(),color:B("color",{length:20}),sortOrder:St("sort_order"),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportLabel_pk`,columns:[m.id]}),ie({name:`${n}_DailyReportLabel_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]})]),W=a.table("DailyReportHub_Label",{hubId:Z("hub_id",{mode:"number"}).notNull(),labelId:Z("label_id",{mode:"number"}).notNull(),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportHub_Label_pk`,columns:[m.hubId,m.labelId]}),ie({name:`${n}_DailyReportHub_Label_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]}),ie({name:`${n}_DailyReportHub_Label_label_id_fk`,columns:[m.labelId],foreignColumns:[d.id]})]),u=a.table("DailyReportUserStatus",{hubId:Z("hub_id",{mode:"number"}).notNull(),userId:Z("user_id",{mode:"number"}).notNull(),isRead:Ve("is_read").default(!1).notNull(),isStarred:Ve("is_starred").default(!1).notNull(),createdAt:te("created_at").notNull(),createdBy:B("created_by",{length:50}).notNull(),updatedAt:te("updated_at").notNull(),updatedBy:B("updated_by",{length:50}).notNull()},m=>[me({name:`${n}_DailyReportUserStatus_pk`,columns:[m.hubId,m.userId]}),ie({name:`${n}_DailyReportUserStatus_hub_id_fk`,columns:[m.hubId],foreignColumns:[g.id]}),ie({name:`${n}_DailyReportUserStatus_user_id_fk`,columns:[m.userId],foreignColumns:[s.id]})]);return{hub:g,internal:y,comment:O,label:d,hubLabel:W,userStatus:u}}function lr(n){let t=He(n.redis),a=new we({defaultTtlMs:n.cacheDefaultTtlMs??6e4},t),s=Xe({...n,cache:a,epochs:t}),g=new _e({redis:n.redis,streamKey:s.streamKey,cache:a,logger:n.logger}),y=ze({authenticate:n.authenticate,service:s,encodeUserId:n.encodeUserId,redis:n.redis,sseReader:g,streamKey:s.streamKey,loginRedirectPath:n.loginRedirectPath,logger:n.logger});return{service:s,cache:a,epochs:t,sseReader:g,streamKey:s.streamKey,...y}}export{_e as DailyReportSseReader,we as SqlResultCache,ze as createDailyReportHandlers,lr as createDailyReportServer,Xe as createDailyReportService,He as createEpochStore,rr as defineDailyReportSchema,Pe as generateETag,Ce as isStreamIdLte,ae as jsonResponseWithETag,Vt as transformJsonArray};
10
10
  //# sourceMappingURL=server.mjs.map