@aiquants/daily-report 0.20.1 → 0.22.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/README.md +278 -13
- package/dist/client.d.mts +213 -45
- package/dist/client.d.ts +213 -45
- package/dist/client.js +5 -5
- package/dist/client.mjs +5 -5
- package/dist/{sse-schema-BdUGThiz.d.ts → ids-stream-BnM6L-Sk.d.ts} +173 -133
- package/dist/{sse-schema-ChSFm-4q.d.mts → ids-stream-DCuiaTit.d.mts} +173 -133
- package/dist/index.d.mts +3 -30
- package/dist/index.d.ts +3 -30
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/server.d.mts +11 -3
- package/dist/server.d.ts +11 -3
- package/dist/server.js +4 -15
- package/dist/server.mjs +4 -15
- package/dist/styles/daily-report.standalone.css +1 -1
- package/package.json +7 -6
package/dist/server.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
"use strict";var et=Object.defineProperty;var er=Object.getOwnPropertyDescriptor;var tr=Object.getOwnPropertyNames;var rr=Object.prototype.hasOwnProperty;var It=t=>{throw TypeError(t)};var nr=(t,e)=>{for(var r in e)et(t,r,{get:e[r],enumerable:!0})},ar=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let d of tr(e))!rr.call(t,d)&&d!==r&&et(t,d,{get:()=>e[d],enumerable:!(o=er(e,d))||o.enumerable});return t};var sr=t=>ar(et({},"__esModule",{value:!0}),t);var Tt=(t,e,r)=>e.has(t)||It("Cannot "+r);var Le=(t,e,r)=>(Tt(t,e,"read from private field"),r?r.call(t):e.get(t)),tt=(t,e,r)=>e.has(t)?It("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),rt=(t,e,r,o)=>(Tt(t,e,"write to private field"),o?o.call(t,r):e.set(t,r),r);var Jr={};nr(Jr,{DailyReportSseReader:()=>$e,DailyReportViewerScope:()=>me,SqlResultCache:()=>Pe,asciiFallbackFileName:()=>Ut,buildVisibleSourceTypeCondition:()=>ht,computeSourceTypeDigest:()=>yt,computeViewerScopeDigest:()=>xe,createDailyReportHandlers:()=>bt,createDailyReportServer:()=>jr,createDailyReportService:()=>gt,createEpochStore:()=>nt,defineDailyReportAuthzResources:()=>Ot,defineDailyReportSchema:()=>Kr,deniesEverySourceType:()=>we,encodeRfc8187:()=>Bt,formatDateValue:()=>re,generateETag:()=>Ve,isSourceTypeVisible:()=>be,isStreamIdLte:()=>Ce,jsonResponseWithETag:()=>pe,normalizeVisibleSourceTypes:()=>mt,sanitizeMediaType:()=>ft,seedDailyReportAuthzResources:()=>qr,transformJsonArray:()=>Vr});module.exports=sr(Jr);var nt=t=>({async getEpoch(e){try{let r=await t?.getClient();if(!r)return null;let o=await r.get(e);return o?Number(o):0}catch{return null}},async incrementEpoch(e){try{let r=await t?.getClient();if(!r)return;await r.incr(e)}catch{}}}),Pe=class{constructor(e,r){this.config=e;this.epochStore=r;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.maybeRefreshAhead=e=>{let r=e.refreshAheadRatio;if(r===void 0)return;let{cacheKey:o}=e,d=this.buckets.get(o);if(!d)return;let c=e.ttlMsOverride??this.config.defaultTtlMs;if(c-(d.expireAt-Date.now())<c*r||this.inFlight.has(o))return;let y;y=(async()=>{let k=e.epochKey?await this.epochStore.getEpoch(e.epochKey):null,u=await e.fetcher();return this.inFlight.get(o)===y&&this.buckets.set(o,{records:u,expireAt:Date.now()+c,epoch:k}),u})(),this.inFlight.set(o,y),y.catch(()=>{}).finally(()=>{this.inFlight.get(o)===y&&this.inFlight.delete(o)})};this.getOrFetch=async e=>{let{cacheKey:r,forceRefresh:o,snapshot:d}=e,c=this.buckets.get(r);if(o&&(this.buckets.delete(r),this.inFlight.delete(r)),!o&&c&&c.expireAt>Date.now())if(e.epochKey){let y=await this.epochStore.getEpoch(e.epochKey);if(y===null||c.epoch===y)return this.maybeRefreshAhead(e),d?c.records.map(k=>structuredClone(k)):c.records;this.buckets.delete(r)}else return this.maybeRefreshAhead(e),d?c.records.map(y=>structuredClone(y)):c.records;if(!o&&this.inFlight.has(r)){let y=await this.inFlight.get(r);return d?y.map(k=>structuredClone(k)):y}let D;D=(async()=>{let y=e.epochKey?await this.epochStore.getEpoch(e.epochKey):null;e.onFetchStart?.();let k=await e.fetcher();if(o||this.inFlight.get(r)===D){let u=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs);this.buckets.set(r,{records:k,expireAt:u,epoch:y}),this.buckets.size>500&&this.cleanExpired()}return k})(),o||this.inFlight.set(r,D);try{let y=await D;return d?y.map(k=>structuredClone(k)):y}finally{this.inFlight.get(r)===D&&this.inFlight.delete(r)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let r of this.buckets.keys())r.startsWith(e)&&this.buckets.delete(r);for(let r of this.inFlight.keys())r.startsWith(e)&&this.inFlight.delete(r)}}cleanExpired(){let e=Date.now();for(let[r,o]of this.buckets.entries())o.expireAt<=e&&this.buckets.delete(r)}};var or=/^\d{4}-\d{2}-\d{2}$/,ir=/^\d{4}\/\d{2}\/\d{2}$/,At=t=>t<10?`0${t}`:`${t}`,Ct=t=>{if(Number.isNaN(t.getTime()))return null;let e=t.getFullYear(),r=At(t.getMonth()+1),o=At(t.getDate());return`${e}-${r}-${o}`};var ie=t=>{if(t==null)return null;if(t instanceof Date)return Ct(t);let e=t.trim();if(e==="")return null;if(or.test(e))return e;if(ir.test(e))return e.replaceAll("/","-");let r=new Date(e);return Ct(r)};var at=t=>{let e=2166136261,r=-624069552;for(let o of t){let d=o.reportHubId;e^=d&255,e=Math.imul(e,16777619),e^=d>>>8&255,e=Math.imul(e,16777619),e^=d>>>16&255,e=Math.imul(e,16777619),e^=d>>>24&255,e=Math.imul(e,16777619),r^=d>>>24&255,r=Math.imul(r,16777619),r^=d>>>16&255,r=Math.imul(r,16777619),r^=d>>>8&255,r=Math.imul(r,16777619),r^=d&255,r=Math.imul(r,16777619);let c=o.businessDate;if(c===null)e^=1,e=Math.imul(e,16777619),r^=1,r=Math.imul(r,16777619);else for(let D=0;D<c.length;D++){let y=c.charCodeAt(D);e^=y&255,e=Math.imul(e,16777619),r^=y&255,r=Math.imul(r,16777619)}}return e^=t.length,e=Math.imul(e,16777619),r^=t.length,r=Math.imul(r,16777619),((e>>>0).toString(16).padStart(8,"0")+(r>>>0).toString(16).padStart(8,"0")).replace(/^0+(?=.)/,"")},qe=(t,e)=>t.businessDate!==e.businessDate?t.businessDate===null?1:e.businessDate===null||t.businessDate>e.businessDate?-1:1:e.reportHubId-t.reportHubId,_t=t=>{for(let e=1;e<t.length;e++)if(qe(t[e-1],t[e])>0)return!1;return!0};var vt=(t,e)=>{let r=t.findIndex(o=>qe({businessDate:o.businessDate,reportHubId:o.reportHubId},e)>0);return r===-1?t.length:r};var de=(t,e,r=console)=>{let o=d=>typeof d=="string"?[`${e} ${d}`]:[e,d];return{debug:(d,...c)=>{t<=0&&r.debug(...o(d),...c)},info:(d,...c)=>{t<=1&&r.info(...o(d),...c)},warn:(d,...c)=>{t<=2&&r.warn(...o(d),...c)},error:(d,...c)=>{t<=3&&r.error(...o(d),...c)}}};var m=require("zod"),lr=m.z.object({name:m.z.string().nullish(),affiliation:m.z.string().nullish()}),ur=m.z.object({name:m.z.string().nullish(),text:m.z.string().nullish(),color:m.z.string().nullish()}),dr=m.z.object({id:m.z.number(),name:m.z.string().nullish(),color:m.z.string().nullish()}),xt=m.z.object({id:m.z.number(),userId:m.z.string().nullish(),userName:m.z.string().nullish(),content:m.z.string().nullish(),createdAt:m.z.string().nullish(),isMine:m.z.boolean()}),cr=m.z.object({id:m.z.string(),fileName:m.z.string(),fileType:m.z.string().nullable(),fileSize:m.z.number().nullable(),createdAt:m.z.string().nullable(),state:m.z.enum(["present","absent","unknown"])}),st=m.z.object({reportHubId:m.z.number(),date:m.z.string().nullish(),createdAt:m.z.string().nullish(),author:m.z.string().nullish(),userId:m.z.string().nullish(),sourceType:m.z.string().nullish(),employeeName:m.z.string().nullish(),updatedBy:m.z.string().nullish(),updatedAt:m.z.string().nullish(),category:m.z.string().nullish(),creationCategory:m.z.string().nullish(),visitTimeFrom:m.z.string().nullish(),visitTimeTo:m.z.string().nullish(),customerName:m.z.string().nullish(),interviewers:m.z.array(lr),subject:m.z.string().nullish(),content:m.z.string().nullish(),externalComments:m.z.array(ur),isRead:m.z.boolean(),isStarred:m.z.boolean(),labels:m.z.array(dr),postedComments:m.z.array(xt),attachments:m.z.array(cr).default([])}),pr=m.z.object({type:m.z.literal("connected")}),ze=m.z.object({type:m.z.literal("status-update"),reportHubId:m.z.number(),statusType:m.z.enum(["star","read"]),value:m.z.boolean(),clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),ot=m.z.string().optional(),it=m.z.object({type:m.z.literal("comment-add"),reportHubId:m.z.number(),comment:xt,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional(),sourceType:ot}),lt=m.z.object({type:m.z.literal("comment-delete"),reportHubId:m.z.number(),commentId:m.z.number(),clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional(),sourceType:ot}),ut=m.z.object({type:m.z.literal("report-create"),reportHubId:m.z.number(),report:st,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),dt=m.z.object({type:m.z.literal("report-update"),reportHubId:m.z.number(),report:st,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),ct=m.z.object({type:m.z.literal("report-publish"),reportHubId:m.z.number(),report:st,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),pt=m.z.object({type:m.z.literal("report-delete"),reportHubId:m.z.number(),clientTempId:m.z.string(),sourceType:ot}),kt=m.z.discriminatedUnion("type",[pr,ze,it,lt,ut,dt,ct,pt]);var Et=require("crypto"),Ve=t=>{let e=JSON.stringify(t);return`"${(0,Et.createHash)("sha256").update(e).digest("hex")}"`};var mr=de(1,"[Response]"),pe=(t,e,r,o=200,d=mr)=>{let c=Ve(r),D=t.headers.get("If-None-Match");d.info(`[jsonResponseWithETag] ETag: ${c}, If-None-Match: ${D}`);let y=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:c});return e&&y.append("Set-Cookie",e),t.method==="GET"&&o===200&&D===c?new Response(null,{status:304,headers:y}):new Response(JSON.stringify(r),{status:o,headers:y})};var Mt=require("events");var Ce=(t,e)=>{let[r,o]=t.split("-").map(Number),[d,c]=e.split("-").map(Number);return r!==d?r<d:o<=c},$e=class{constructor(e){this.config=e;this._emitter=new Mt.EventEmitter;this._state="idle";this._refCount=0;this._lastId="$";this._emitter.setMaxListeners(0),this._logger=e.logger??de(1,"[SSE Reader]")}subscribe(e,r){return this._emitter.on("entry",e),r&&this._emitter.on("error",r),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),r&&this._emitter.removeListener("error",r),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="$"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"&&this._refCount!==0){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitError(e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitError(new Error("Failed to create Redis client for SSE reader"));return}if(this._client.on("error",e=>{this._logger.error("Redis client error:",e)}),this._lastId==="$")try{let e=await this.config.redis?.getClient();if(e){let r=await e.xRevRange(this.config.streamKey,"+","-",{COUNT:1});this._lastId=r.length>0?r[0].id:"0-0"}}catch(e){this._logger.warn("Failed to resolve stream tail anchor; falling back to $:",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 r of e)for(let o of r.messages){this._lastId=o.id;try{let d=o.message?.data?JSON.parse(o.message.data):null,c=d?.type;if((c==="report-create"||c==="report-delete"||c==="report-publish")&&this.config.cache.invalidatePrefix("daily-report:ids"),c==="comment-add"||c==="comment-delete"||c==="status-update"){let D=d?.reportHubId;typeof D=="number"&&(this.config.cache.invalidate(`daily-report:detail:${D}`),this.config.cache.invalidatePrefix(`daily-report:detail:${D}:user:`))}}catch{}this._emitter.emit("entry",{id:o.id,message:o.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitError(e instanceof Error?e:new Error(String(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==="stopping";)await new Promise(e=>setTimeout(e,50))}}_emitError(e){this._emitter.listenerCount("error")>0?this._emitter.emit("error",e):this._logger.error("SSE reader error (no error listeners):",e)}};var Ue=require("drizzle-orm");var yr="",hr=64,fr=t=>t.toLowerCase(),br=t=>t.trim().toLowerCase();function mt(t){if(t==null)return null;if(!Array.isArray(t))return new Set;let e=new Set;for(let r of t){if(typeof r!="string")continue;let o=br(r);o.length>0&&e.add(o)}return e}function be(t,e){return t===null?!0:e==null?!1:t.has(fr(e))}function we(t){return t!==null&&t.size===0}function ht(t,e){if(e!==null)return e.size===0?Ue.sql`1 = 0`:(0,Ue.inArray)(Ue.sql`LOWER(${t})`,[...e])}var _e,ve,Be=class Be{constructor(e,r){tt(this,_e);tt(this,ve);rt(this,_e,e),rt(this,ve,r)}get visible(){return Le(this,_e)===null?null:new Set(Le(this,_e))}get commentable(){return Le(this,ve)===null?null:new Set(Le(this,ve))}static restrictTo(e){let r=typeof e=="object"&&e!==null&&"read"in e,o=mt(r?e.read:e),d=r?e.comment:void 0;if(d===void 0)return new Be(o,o);let c=mt(d),D=new Set;for(let y of c??[])o.has(y)&&D.add(y);return new Be(o,D)}static unrestricted(e){return new Be(null,null)}};_e=new WeakMap,ve=new WeakMap;var me=Be;function xe(t){let e=yt(t.visible),r=yt(t.commentable);return e===r?e:`d:${e.length}:${e}${r}`}function yt(t){if(t===null)return"all";if(t.size===0)return"none";let e=[...t].sort().map(o=>`${o.length}:${o}`).join(yr);if(e.length<=hr)return`s:${e}`;let r=2166136261;for(let o=0;o<e.length;o++)r^=e.charCodeAt(o),r=Math.imul(r,16777619);return`sh:${(r>>>0).toString(16)}`}var gr=(t,e)=>{let r=new Headers({"Content-Type":"application/json"});return e?.setCookie&&r.append("Set-Cookie",e.setCookie),new Response(JSON.stringify(t),{status:e?.status??200,headers:r})},je=30,$t=4e3,Rr="stream interrupted by server error",Dr=/^\d{4}-\d{2}-\d{2}$/,wr=15e3,Nt=Symbol("ids-stream-heartbeat"),Sr=12,Ir=/^[0-9a-f]{1,16}$/,Tr=t=>{let e=t.searchParams.get("cursor_report_hub_id"),r=t.searchParams.get("cursor_business_date"),o=t.searchParams.get("cursor_snapshot"),d=o!==null&&Ir.test(o)?o:null;if(e===null)return r===null?{cursor:null,snapshot:d}:{invalid:!0};let c=Number.parseInt(e,10);return!Number.isSafeInteger(c)||String(c)!==e||c<=0?{invalid:!0}:r===null?{cursor:{businessDate:null,reportHubId:c},snapshot:d}:Dr.test(r)?{cursor:{businessDate:r,reportHubId:c},snapshot:d}:{invalid:!0}};async function*Lt(t,e,r,o){let d=e?vt(t,e):0,c=!0;for(;;){let D=t.slice(d,d+(c?r:$t));d+=D.length;let y=d>=t.length,k=D[D.length-1];if(yield{kind:"chunk",items:D,nextCursor:y||!k?null:{businessDate:k.businessDate,reportHubId:k.reportHubId},isLast:y,...c?{total:t.length}:{},snapshot:o.snapshot,...c&&o.restarted?{restarted:!0}:{}},c=!1,y)return}}var Pt=(t,e,r,o)=>{let d=new TextEncoder,c=!1,D=null,y=new ReadableStream({async pull(u){if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}let Y=null;try{D===null&&(D=e.next());let h=new Promise(ye=>{Y=setTimeout(()=>ye(Nt),wr)}),V=await Promise.race([D,h]);if(Y!==null&&(clearTimeout(Y),Y=null),V===Nt){if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(d.encode(`
|
|
2
|
-
`));return}D=null;let{value:
|
|
3
|
-
`))}catch(
|
|
4
|
-
`)),u.close()}catch{}}},cancel(){c=!0,e.return(void 0).catch(()=>{})}}),k=new Headers({"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"private, no-cache, no-transform","X-Content-Type-Options":"nosniff"});return t&&k.append("Set-Cookie",t),new Response(y,{status:200,headers:k})},Ar=32*1024*1024,Cr=60,_r=4,vr=12e4,xr=1024,kr=60,Er=5,Mr=new Set(["image/png","image/jpeg","image/gif","image/webp","application/pdf","text/plain"]),Nr=/^[\x20-\x7E]+$/,Lr=/^[\w.+-]+\/[\w.+-]+/,ft=t=>t&&Nr.test(t)&&Lr.test(t)?t:null,Bt=t=>encodeURIComponent(t).replace(/['()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`),Ut=t=>t.replace(/[^\x20-\x7E]/g,"_").replace(/["\\]/g,"_"),Pr=t=>{switch(t){case"not_found":case"denied":case"invalid_path":return 404;case"too_large":return 413;default:return 502}},$r={404:"Attachment not found",413:"Attachment too large",502:"Attachment storage unavailable"},Br=t=>{let e=new Map;return(r,o)=>{let d=e.get(r);d&&e.delete(r);let c=d??{tokens:t,lastRefillMs:o},D=Math.max(0,o-c.lastRefillMs);D>0&&(c.tokens=Math.min(t,c.tokens+D*t/6e4),c.lastRefillMs=o);let y=c.tokens>=1;for(y&&(c.tokens-=1),e.set(r,c);e.size>xr;){let k=e.keys().next();if(k.done)break;e.delete(k.value)}return y}},Ur=t=>{let e=0;return{tryAcquire:()=>e>=t?!1:(e+=1,!0),release:()=>{e>0&&(e-=1)}}},Hr=(t,e,r)=>{let o=setTimeout(e,r);o.unref?.();let d=()=>{clearTimeout(o),e()},c=!1;return new ReadableStream({pull(D){if(c){D.close(),d();return}c=!0,D.enqueue(t)},cancel(){d()}})},Or=(t,e,r,o)=>{if(r===null&&o===null)return!0;let d=typeof e.sourceType=="string"?e.sourceType:void 0;switch(t.type){case"connected":case"status-update":return!0;case"report-create":case"report-update":case"report-publish":return be(r,t.report.sourceType);case"comment-add":case"comment-delete":return be(o,d??"Internal");case"report-delete":return be(r,d)}},Yr=["externalComments","postedComments"],Fr=(t,e,r)=>{if(r===null||t.type!=="report-create"&&t.type!=="report-update"&&t.type!=="report-publish"||be(r,t.report.sourceType))return!1;let o=e.report;if(typeof o!="object"||o===null)return!1;let d=o;for(let c of Yr)d[c]=[];return!0};function bt(t){let{authenticate:e,service:r,encodeUserId:o,redis:d,sseReader:c,streamKey:D}=t,y=t.loginRedirectPath??"/auth/login",k=t.logger??de(3,"[DailyReportAPI]"),u=t.logger??de(3,"[DailyReportVisibility]"),Y=t.logger??de(1,"[DailyReportSSE]"),h=t.logger??de(1,"[DailyReportAttachment]"),V=t.attachmentMaxBytes??Ar,K=Br(t.attachmentRateLimitPerMinute??Cr),F=Ur(t.attachmentConcurrency??_r),ye=async(S,H="initial")=>{let E=t.resolveVisibleSourceTypes;if(!E)return me.unrestricted("no visibility port injected: this deployment does not restrict by source type");try{let A=await E(S,{reason:H});return A==null?me.unrestricted("visibility port returned null/undefined: this deployment opts out of source-type filtering"):me.restrictTo(A)}catch(A){return u.error("resolveVisibleSourceTypes threw; failing closed (deny all)",A),me.restrictTo([])}},ke=async({request:S})=>{let{user:H,cookie:E}=await e(S,{failureRedirect:y}),A=new Headers;E&&A.append("Set-Cookie",E);let f=await r.getUserIdByExternalId(H.id),B=f?o(f):null;return{data:{user:H,userId:B},headers:A}},Ee={"business-date":async(S,H,E,A,f)=>{let B=ie(S.searchParams.get("businessDate")),q=S.searchParams.get("forceRefresh")==="true";if(!B)return pe(E,H,{error:{message:"Invalid business date"}},400);let v=await r.getDailyReportsByBusinessDateByExternalId(f,B,A.id,{forceRefresh:q});return pe(E,H,{businessDate:B,reports:v},200)},"ids-stream":async(S,H,E,A,f)=>{let B=Tr(S);if("invalid"in B)return pe(E,H,{error:{message:"Invalid cursor"}},400);let q=S.searchParams.get("forceRefresh")==="true",v=!1,I=null,C=null,z=new Promise((N,M)=>{I=N,C=M});z.catch(()=>{});let ce=r.getDailyReportIdsByExternalId(f,A.id,{forceRefresh:q,onFetchStart:B.cursor?void 0:()=>{v=!0,r.getDailyReportIdsFirstPageByExternalId(f,A.id,je).then(N=>I?.(N),N=>C?.(N))}});if(ce.catch(()=>{}),B.cursor){let N=await ce,M=at(N),$=B.snapshot!==null&&B.snapshot===M;return Pt(H,Lt(N,$?B.cursor:null,je,{snapshot:M,restarted:!$}),E,k)}let P=(async function*(){let N=await Promise.race([ce.then(L=>({kind:"full",items:L}),L=>({kind:"full-error",error:L})),z.then(L=>({kind:"page",items:L}),()=>({kind:"page-error"}))]),M=null,$=!1;if(N.kind==="full")M=N.items;else if(N.kind==="page"){let L=N.items;if(L.length<je){yield{kind:"chunk",items:L,nextCursor:null,isLast:!0,total:L.length};return}yield{kind:"chunk",items:L,nextCursor:null,isLast:!1,provisional:!0},$=!0}else if(N.kind==="full-error"&&v){let L=await z.catch(()=>null);L&&L.length>0&&(yield{kind:"chunk",items:L,nextCursor:null,isLast:!1,provisional:!0})}M===null&&(M=await ce),yield*Lt(M,null,$?$t:je,{snapshot:at(M)})})();return Pt(H,P,E,k)},report:async(S,H,E,A,f)=>{let B=S.searchParams.get("reportHubId"),q=S.searchParams.get("forceRefresh")==="true",v=B?Number.parseInt(B,10):NaN;if(!Number.isFinite(v)||v<=0)return pe(E,H,{error:{message:"Invalid reportHubId"}},400);let I=await r.getDailyReportDetailByIdByExternalId(f,v,A.id,{snapshot:!0,forceRefresh:q});return I?pe(E,H,{report:I},200):pe(E,H,{error:{message:"Report not found"}},404)}};return{index:{loader:ke},api:{loader:async({request:S,params:H})=>{let{user:E,cookie:A}=await e(S,{failureRedirect:null}),f=A??null;if(!E)return pe(S,f,{error:{message:"Unauthorized"}},401);if(S.method!=="GET")return pe(S,f,{error:{message:"Method not allowed"}},405);let B=H.endpoint??"",q=Ee[B];if(!q)return pe(S,f,{error:{message:"Unknown endpoint"}},404);let v=Date.now();try{let I=new URL(S.url),C=await ye(S);return await q(I,f,S,E,C)}catch(I){let C=Date.now()-v,z=I instanceof Error?I:new Error(String(I));return k.error(`500 endpoint=${B} elapsed=${C}ms name=${z.name} code=${"code"in z?z.code:"N/A"} message=${z.message}`),k.error("Stack:",z.stack),pe(S,f,{error:{message:"Internal Server Error"}},500)}},action:async({request:S,params:H})=>{let{user:E,cookie:A}=await e(S,{failureRedirect:null}),f=(q,v)=>gr(q,{...v,setCookie:A});if(!E)return f({error:"Unauthorized"},{status:401});let B=Date.now();try{if(H.endpoint!=="action")return f({error:"Unknown endpoint"},{status:404});let v=await r.getUserIdByExternalId(E.id);if(!v)return f({error:"User not found"},{status:404});let I=await ye(S),C=await S.formData(),z=C.get("intent"),ce=C.get("reportHubId"),P=ce?Number(ce):NaN,N=C.get("businessDate"),M=Number(C.get("operationTimestamp")),$=C.get("clientTempId");if(z==="clearCache")return t.enableDevCacheClear?(await r.clearCache(),f({status:"OK",intent:"clearCache"})):f({error:"Invalid intent"},{status:400});if(!$)return f({error:"clientTempId required"},{status:400});if(z!=="create"&&(!P||Number.isNaN(P)))return f({error:"Invalid reportHubId"},{status:400});let L=async(w,O,Z)=>{let he=C.get(O);if(he===null)return f({error:`${O} required`},{status:400});try{let le=await Z(he==="true");return f({status:"OK",intent:w,updatedStatus:{isStarred:le.isStarred,isRead:le.isRead},operationTimestamp:M,reportHubId:String(P),clientTempId:$})}catch(le){if(le instanceof Error&&le.message==="Not Found")return f({error:"Report not found"},{status:404});throw le}};switch(z){case"create":{if(!N)return f({error:"businessDate required"},{status:400});let w=await r.createDailyReport(v,N,$);return f({status:"OK",intent:"create",report:w,reportHubId:String(w.reportHubId),clientTempId:$})}case"update":{let w=C.get("title"),O=C.get("content");try{return await r.updateDailyReport(P,v,{title:w,content:O},$),f({status:"OK",intent:"update",reportHubId:String(P),clientTempId:$})}catch(Z){if(Z instanceof Error){if(Z.message==="Unauthorized")return f({error:"Unauthorized"},{status:403});if(Z.message==="Not Found")return f({error:"Report not found"},{status:404})}throw Z}}case"publish":try{let w=await r.publishDailyReport(P,v,$);return f({status:"OK",intent:"publish",reportHubId:String(P),clientTempId:$,report:w})}catch(w){if(w instanceof Error){if(w.message==="Unauthorized")return f({error:"Unauthorized"},{status:403});if(w.message==="Not Found")return f({error:"Report not found"},{status:404})}throw w}case"delete":try{return await r.deleteDailyReport(P,v,$),f({status:"OK",intent:"delete",reportHubId:String(P),clientTempId:$})}catch(w){if(w instanceof Error){if(w.message==="Unauthorized")return f({error:"Unauthorized"},{status:403});if(w.message==="Not Found")return f({error:"Report not found"},{status:404})}throw w}case"toggleStar":return await L("toggleStar","isStarred",w=>r.setStarStatus(I,v,P,N,w,$));case"toggleRead":return await L("toggleRead","isRead",w=>r.setReadStatus(I,v,P,N,w,$));case"addComment":{let w=C.get("content");if(!w)return f({error:"Content required"},{status:400});try{let O=await r.addComment(I,v,P,w,N,$),Z={...O,userId:O.userId};return f({status:"OK",intent:"addComment",newComment:Z,reportHubId:String(P),clientTempId:$})}catch(O){if(O instanceof Error){if(O.message==="Not Found")return f({error:"Report not found"},{status:404});if(O.message.startsWith("Comments are restricted"))return f({error:"Comments are restricted for this report"},{status:403})}throw O}}case"deleteComment":{let w=Number(C.get("commentId"));if(!w||Number.isNaN(w))return f({error:"Invalid commentId"},{status:400});try{return await r.deleteComment(I,v,P,w,N,$),f({status:"OK",reportHubId:String(P),deletedCommentId:String(w),clientTempId:$})}catch(O){if(O instanceof Error){if(O.message==="Unauthorized")return f({error:"Unauthorized"},{status:403});if(O.message==="Not Found")return f({error:"Comment not found"},{status:404})}throw O}}default:return f({error:"Invalid intent"},{status:400})}}catch(q){if(q instanceof Response)throw q;let v=Date.now()-B,I=q instanceof Error?q:new Error(String(q));return k.error(`500 action elapsed=${v}ms name=${I.name} message=${I.message}`),k.error("Stack:",I.stack),f({error:"Internal Server Error"},{status:500})}}},sse:{loader:async({request:S,params:H})=>{let{user:E,cookie:A}=await e(S,{failureRedirect:null}),f=ne=>A===void 0?ne:{...ne??{},"Set-Cookie":A};if(!E)return new Response("Unauthorized",{status:401,headers:f()});let B=await r.getUserIdByExternalId(E.id);if(!B)return new Response("Forbidden",{status:403,headers:f()});if(H.endpoint!=="updates")return new Response("Not Found",{status:404,headers:f()});let q=await ye(S),v=q.visible,I=q.commentable,C=0,z=0,P=new URL(S.url).searchParams.get("lastEventId")||S.headers.get("Last-Event-ID"),N=new TextEncoder,M=null,$=null,L=null,w=!1,O=()=>{if(!w){if(w=!0,$&&(clearInterval($),$=null),L&&(L(),L=null),M)try{M.desiredSize!==null&&M.close()}catch{}finally{M=null}w=!1}},Z=ne=>{M&&M.desiredSize!==null&&M.enqueue(N.encode(`id: ${ne}
|
|
5
|
-
data: ${JSON.stringify({type:"connected"})}
|
|
6
|
-
|
|
7
|
-
`))},he=(ne,ee)=>{if(ee.data)try{let G=JSON.parse(ee.data),x=kt.safeParse(G);if(!x.success){Y.error("SSE message validation failed:",x.error.format());return}let J=x.data,ue=typeof G.recipientRawUserId=="number"?G.recipientRawUserId:void 0;if(J.type==="status-update"){if(ue===void 0||ue!==B)return}else if(ue!==void 0&&ue!==B)return;if(!Or(J,G,v,I)){Z(ne);return}let Ge=Fr(J,G,I),fe;if("recipientRawUserId"in G){let{recipientRawUserId:Me,...ge}=G;fe=JSON.stringify(ge)}else Ge?fe=JSON.stringify(G):fe=ee.data;M&&M.desiredSize!==null&&M.enqueue(N.encode(`id: ${ne}
|
|
8
|
-
data: ${fe}
|
|
9
|
-
|
|
10
|
-
`))}catch(G){Y.error(`[SSE:${B}] processEntry error:`,G)}},le=new ReadableStream({async start(ne){M=ne,$=setInterval(()=>{try{if(M&&M.desiredSize!==null){if(M.enqueue(N.encode(`: keep-alive
|
|
11
|
-
|
|
12
|
-
`)),++C%Sr===0){let x=++z;ye(S,"refresh").then(J=>{x===z&&(v=J.visible,I=J.commentable)})}}else O()}catch{O()}},5e3),S.signal.addEventListener("abort",()=>{O()});let ee=P||"0-0",G=null;if(L=c.subscribe(x=>{Ce(x.id,ee)||(G===null&&(G=x.id),ee=x.id,he(x.id,x.message))},x=>{Y.error(`[SSE:${B}] Fan-Out reader error:`,x),O()}),!P)try{let x=await d?.getClient();if(x){let J=await x.xRevRange(D,"+","-",{COUNT:1});J.length>0&&!Ce(J[0].id,ee)&&(ee=J[0].id)}}catch{}if(M&&M.desiredSize!==null){let x=`data: ${JSON.stringify({type:"connected"})}
|
|
13
|
-
|
|
14
|
-
`,J=ee!=="0-0"?`id: ${ee}
|
|
15
|
-
${x}`:x;M.enqueue(N.encode(J))}if(P)try{let x=await d?.getClient();if(x){let J=await x.xRange(D,P,"+",{COUNT:1e3});for(let ue of J)ue.id!==P&&(G!==null&&Ce(G,ue.id)||(Ce(ue.id,ee)||(ee=ue.id),he(ue.id,ue.message)))}}catch(x){Y.error(`[SSE:${B}] catch-up xRange error:`,x)}},cancel(){O()}});return new Response(le,{headers:f({"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"})})}},attachment:{loader:async({request:S,params:H})=>{let E=null,A=(f,B,q)=>{let v=new Headers({"Content-Type":"application/json"});return q!==void 0&&v.set("Retry-After",String(q)),E&&v.append("Set-Cookie",E),new Response(JSON.stringify({error:{message:B}}),{status:f,headers:v})};try{let{user:f,cookie:B}=await e(S,{failureRedirect:null});if(E=B??null,!f)return A(401,"Unauthorized");if(S.method!=="GET"&&S.method!=="HEAD")return A(405,"Method not allowed");let q=t.attachmentIdCodec,v=t.readAttachment;if(!(q&&v))return A(404,"Attachment not found");let I=H.token??"",C=q.decode(I);if(C===null||!Number.isSafeInteger(C)||C<=0)return A(400,"Invalid attachment token");let z=await r.getUserIdByExternalId(f.id);if(!z)return A(403,"Forbidden");if(!K(z,Date.now()))return h.error(`429 attachment=${C} viewer=${z} reason=rate_limit`),A(429,"Too many requests",kr);let ce=await ye(S),P=await r.getAttachmentForUser(ce,C,z);if(!P)return h.error(`404 attachment=${C} viewer=${z} reason=not_visible`),A(404,"Attachment not found");if(P.fileSize!=null&&P.fileSize>V)return h.error(`413 attachment=${C} viewer=${z} reason=db_size`),A(413,"Attachment too large");if(!F.tryAcquire())return h.error(`503 attachment=${C} viewer=${z} reason=concurrency`),A(503,"Too many concurrent downloads",Er);let N=!1,M=()=>{N||(N=!0,F.release())},$=!1;try{let L=S.method==="HEAD",w=await v(P.filePath,{maxBytes:V,head:L,principal:o(z)});if(!w.ok){let x=Pr(w.reason);return w.reason==="not_found"&&r.markAttachmentMissing(C).catch(J=>{h.error(`markAttachmentMissing failed attachment=${C} message=${J instanceof Error?J.message:"unknown"}`)}),h.error(`${x} attachment=${C} viewer=${z} reason=${w.reason} code=${w.code??"-"}`),A(x,$r[x]??"Attachment storage unavailable")}let O=ft(P.fileType)??ft(w.contentType)??"application/octet-stream",Z=Mr.has(O),he=new URL(S.url).searchParams.get("download")==="1",le=Z?O:"application/octet-stream",ne=Z&&!he?"inline":"attachment",ee=w.size??w.bytes.byteLength,G=new Headers({"Content-Type":le,"Content-Length":String(ee),"Content-Disposition":`${ne}; filename="${Ut(P.fileName)}"; filename*=UTF-8''${Bt(P.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return E&&G.append("Set-Cookie",E),r.markAttachmentPresent(C).catch(x=>{h.error(`markAttachmentPresent failed attachment=${C} message=${x instanceof Error?x.message:"unknown"}`)}),h.info(`200 attachment=${C} viewer=${z} type=${le} disposition=${ne} bytes=${ee}`),L?new Response(null,{status:200,headers:G}):($=!0,new Response(Hr(w.bytes,M,vr),{status:200,headers:G}))}finally{$||M()}}catch(f){if(f instanceof Response)throw f;return h.error(`500 attachment=? viewer=? reason=unexpected message=${f instanceof Error?f.message:"unknown"}`),A(500,"Attachment request failed")}}}}}var Ht=require("@aiquants/mssql"),s=require("drizzle-orm");var Se=t=>(0,s.getColumns)(t),re=(t,e)=>{if(!t)return null;let r=t instanceof Date?t:new Date(t);if(Number.isNaN(r.getTime()))return typeof t=="string"?t:null;let o=r.getFullYear(),d=o<0?`-${String(-o).padStart(4,"0")}`:String(o).padStart(4,"0"),c=String(r.getMonth()+1).padStart(2,"0"),D=String(r.getDate()).padStart(2,"0");if(e==="YYYY-MM-DD")return`${d}-${c}-${D}`;let y=String(r.getHours()).padStart(2,"0"),k=String(r.getMinutes()).padStart(2,"0"),u=String(r.getSeconds()).padStart(2,"0");return`${d}-${c}-${D} ${y}:${k}:${u}`};function gt(t){let{db:e,tables:r,userTable:o,resolveUserId:d,encodeUserId:c,redis:D,cache:y,epochs:k}=t,{hub:u,internal:Y,comment:h,label:V,hubLabel:K,userStatus:F}=r,ye=t.externalSources??[],ke=t.draftLabelNames&&t.draftLabelNames.length>0?t.draftLabelNames:[t.draftLabelName??"\u4E0B\u66F8\u304D"],Ee=ke[0]??"\u4E0B\u66F8\u304D",te=t.logger??de(1,"[DailyReportService]"),Je=n=>(0,Ht.runWithTransactionRetry)(a=>e.transaction(i=>a(()=>n(i))),t.transactionRetry),Ie="daily-report:ids",Rt=t.idsTtlMs??18e4,S="daily-report:ids:epoch",H="daily-report:business-date:",E=t.businessDateTtlMs??3e5,A="daily-report:date-epoch:",f="daily-report:detail-epoch:",q=`${t.streamKey??"daily-report:sse-stream"}:v2`,v=t.streamMaxLen??1e4,I=n=>k.incrementEpoch(n),C=n=>ht(u.sourceType,n),z=(n,a)=>`${Ie}:user:${n}:st:${a}`,ce=n=>`${Ie}:user:${n}:`,P=(n,a,i)=>`daily-report:date:${n}:user:${a}:st:${i}`,N=(n,a)=>`daily-report:date:${n}:user:${a}:`,M=(n,a,i)=>`daily-report:detail:${n}:user:${a}:st:${i}`,$=(n,a)=>`daily-report:detail:${n}:user:${a}:`,L=async(n,a)=>{let i=await D?.getClient();if(!i){te.warn(`[SSE] Redis client unavailable (${a})`);return}let p=Date.now();try{await i.xAdd(q,"*",{data:JSON.stringify(n)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:v}});let b=Date.now()-p;b>1e3&&te.warn(`[SSE] Slow publish (${a}): ${b}ms`)}catch(b){te.error(`[SSE] Redis publish failed (${a}):`,b)}},w=n=>n==null||n===""?null:/^\d+$/.test(n)?c(Number(n)):n,O=()=>{let n={};for(let a of ye)n[`ext_${a.sourceType}`]=Se(a.table);return n},Z=n=>{let a=n;for(let i of ye)a=a.leftJoin(i.table,(0,s.and)((0,s.eq)(u.sourceType,i.sourceType),(0,s.eq)(u.sourceIdNum,i.idColumn)));return a},he=(n,a,i)=>{let{hub:p,internal:b}=a,g=p.summary,R=[],T=null,_=null,Q=null,j=null,W=null,ae=null,Te=[],De=ye.find(U=>U.sourceType===p.sourceType),Ae=De?a[`ext_${De.sourceType}`]:void 0;if(De&&Ae){let U=De.mapRow(Ae);U.content!==void 0&&(g=U.content),U.employeeName!==void 0&&(ae=U.employeeName),U.category!==void 0&&(T=U.category),U.creationCategory!==void 0&&(_=U.creationCategory),U.visitTimeFrom!==void 0&&(Q=U.visitTimeFrom),U.visitTimeTo!==void 0&&(j=U.visitTimeTo),U.customerName!==void 0&&(W=U.customerName),U.interviewers!==void 0&&(R=U.interviewers),U.externalComments!==void 0&&(Te=U.externalComments)}else p.sourceType==="Internal"&&b&&(g=b.body);let Re=(a.labels??[]).map(U=>({id:U.id,name:U.name,color:U.color})),se=a.postedCommentRows??[],X=be(n.commentable,p.sourceType),oe=_?ke.includes(_):!1,Ze=fe?.[0]??null;return oe&&Ze&&!Re.some(U=>U.id===Ze)&&Re.push({id:Ze,name:Ee,color:null}),{reportHubId:p.id,date:re(p.businessDate,"YYYY-MM-DD"),author:a.creatorName??w(p.createdBy)??"",userId:p.userId?c(p.userId):"",sourceType:p.sourceType??"Internal",createdAt:re(p.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:re(p.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:w(p.updatedBy),employeeName:ae??a.creatorName??w(p.createdBy),category:T,creationCategory:_,visitTimeFrom:Q,visitTimeTo:j,customerName:W,interviewers:R,subject:p.title,content:g,externalComments:X?Te:[],isRead:a.isRead??!1,isStarred:a.isStarred??!1,labels:Re,postedComments:se.filter(U=>X||i!==void 0&&U.userId===i).map(U=>({...U,userId:c(U.userId),isMine:i?U.userId===i:!1})),attachments:a.attachments}},le=async(n,a)=>{let i=(0,s.aliasedTable)(K,"draft_label"),p=await ge();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).from(u).leftJoin(i,(0,s.and)((0,s.eq)(i.hubId,u.id),(0,s.inArray)(i.labelId,p))).where((0,s.and)((0,s.isNull)(u.deletedAt),(0,s.or)((0,s.eq)(u.userId,a),(0,s.isNull)(u.userId),(0,s.isNull)(i.hubId)),C(n.visible))).orderBy((0,s.desc)(u.businessDate),(0,s.desc)(u.id))).map(g=>({...g,businessDate:re(g.businessDate,"YYYY-MM-DD")}))},ne=async(n,a,i)=>{let p=await J(a);if(!p)return[];if(we(n.visible))return[];let b=(0,s.aliasedTable)(K,"draft_label"),g=await ge();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).top(i).from(u).leftJoin(b,(0,s.and)((0,s.eq)(b.hubId,u.id),(0,s.inArray)(b.labelId,g))).where((0,s.and)((0,s.isNull)(u.deletedAt),(0,s.or)((0,s.eq)(u.userId,p),(0,s.isNull)(u.userId),(0,s.isNull)(b.hubId)),C(n.visible))).orderBy((0,s.desc)(u.businessDate),(0,s.desc)(u.id))).map(T=>({...T,businessDate:re(T.businessDate,"YYYY-MM-DD")}))},ee=async(n,a)=>{let i=await Z(e.select({hub:Se(u),internal:Se(Y),creatorName:o.displayName,...O()}).from(u)).leftJoin(Y,(0,s.eq)(u.id,Y.hubId)).leftJoin(o,(0,s.eq)(u.userId,o.id)).where((0,s.and)((0,s.eq)(u.businessDate,s.sql`${a}`),(0,s.isNull)(u.deletedAt),C(n.visible))).orderBy((0,s.desc)(u.id)),p=await Ye(i.map(b=>b.hub.id));return i.map(b=>he(n,{...b,attachments:p.get(b.hub.id)??[]}))},G=n=>`${H}${n}`,x=new Map,J=async n=>{if(!t.disableUserIdCache&&x.has(n))return x.get(n)??null;let a=await d(n);return a!==null&&!t.disableUserIdCache&&x.set(n,a),a},ue=async(n,a,{forceRefresh:i=!1,snapshot:p=!1,ttlMsOverride:b,onFetchStart:g}={})=>{let R=await J(a);if(!R)return[];if(we(n.visible))return[];let T=z(R,xe(n));return y.getOrFetch({cacheKey:T,fetcher:async()=>{let _=await le(n,R);return _t(_)?_:(te.warn("[DailyReportService] ids array is not in stream order; re-sorting (check SQL ORDER BY vs compareIdsStreamOrder, or concurrent row movement during the scan)"),[..._].sort(qe))},onFetchStart:g,forceRefresh:i,snapshot:p,ttlMsOverride:b??Rt,epochKey:S,refreshAheadRatio:.5})},Ge=(n,a,{forceRefresh:i=!1,snapshot:p=!1,ttlMsOverride:b}={})=>{let g=ie(a);return g?we(n.visible)?Promise.resolve([]):y.getOrFetch({cacheKey:`${G(g)}:st:${xe(n)}`,fetcher:()=>ee(n,g),forceRefresh:i,snapshot:p,ttlMsOverride:b??E}):Promise.resolve([])},fe=null,Me=async()=>(fe!==null||(fe=(await e.select({id:V.id}).from(V).where((0,s.inArray)(V.name,ke)).orderBy(V.id)).map(a=>a.id)),fe),ge=async()=>{let n=await Me();return n.length>0?n:[-1]},Qe=async()=>{let n=await Me();if(n.length===0)return null;let[a]=await e.select({id:V.id}).top(1).from(V).where((0,s.eq)(V.name,Ee));return a?.id??n[0]},Yt=(n,a)=>a!=null?"absent":n!=null?"present":"unknown",Ye=async n=>{let a=new Map,i=r.attachment,p=t.attachmentIdCodec;if(n.length===0||!i||!p)return a;let b=await e.select({id:i.id,hubId:i.hubId,fileName:i.fileName,fileType:i.fileType,fileSize:i.fileSize,createdAt:i.createdAt,objectCheckedAt:i.objectCheckedAt,objectMissingAt:i.objectMissingAt}).from(i).where((0,s.inArray)(i.hubId,n)).orderBy((0,s.asc)(i.createdAt),(0,s.asc)(i.id));for(let g of b){let R={id:p.encode(Number(g.id)),fileName:String(g.fileName),fileType:g.fileType?String(g.fileType):null,fileSize:g.fileSize!=null?Number(g.fileSize):null,createdAt:re(g.createdAt,"YYYY-MM-DD HH:mm:ss"),state:Yt(g.objectCheckedAt,g.objectMissingAt)},T=a.get(Number(g.hubId));T?T.push(R):a.set(Number(g.hubId),[R])}return a},Ft=async(n,a,i)=>{let p=r.attachment;if(!p||we(n.visible))return null;let b=await ge(),g=(0,s.aliasedTable)(K,"draft_label");return(await e.select({fileName:p.fileName,filePath:p.filePath,fileType:p.fileType,fileSize:p.fileSize}).top(1).from(p).innerJoin(u,(0,s.eq)(u.id,p.hubId)).leftJoin(g,(0,s.and)((0,s.eq)(g.hubId,u.id),(0,s.inArray)(g.labelId,b))).where((0,s.and)((0,s.eq)(p.id,a),(0,s.isNull)(u.deletedAt),(0,s.or)((0,s.eq)(u.userId,i),(0,s.isNull)(g.hubId)),C(n.visible))))[0]??null},qt=async n=>{let a=r.attachment;if(!a)return;let i=new Date;try{await e.update(a).set({objectCheckedAt:i,objectMissingAt:i,updatedAt:i}).where((0,s.eq)(a.id,n))}catch(p){te.error("markAttachmentMissing failed",p)}},zt=async n=>{let a=r.attachment;if(!a)return;let i=new Date;try{await e.update(a).set({objectCheckedAt:i,objectMissingAt:null,updatedAt:i}).where((0,s.eq)(a.id,n))}catch(p){te.error("markAttachmentPresent failed",p)}},Vt=async(n,a,i,{forceRefresh:p=!1,snapshot:b=!1,ttlMsOverride:g}={})=>{let R=await J(i);if(!R)return[];let T=ie(a);if(!T)return[];if(we(n.visible))return[];let _=P(T,R,xe(n));return y.getOrFetch({cacheKey:_,fetcher:async()=>{let Q=await ge(),j=(0,s.aliasedTable)(K,"draft_label"),W=await Z(e.select({hub:Se(u),internal:Se(Y),isRead:F.isRead,isStarred:F.isStarred,creatorName:o.displayName,...O()}).from(u)).leftJoin(Y,(0,s.eq)(u.id,Y.hubId)).leftJoin(F,(0,s.and)((0,s.eq)(u.id,F.hubId),(0,s.eq)(F.userId,R))).leftJoin(j,(0,s.and)((0,s.eq)(j.hubId,u.id),(0,s.inArray)(j.labelId,Q))).leftJoin(o,(0,s.eq)(u.userId,o.id)).where((0,s.and)((0,s.eq)(u.businessDate,s.sql`${T}`),(0,s.isNull)(u.deletedAt),(0,s.or)((0,s.eq)(u.userId,R),(0,s.isNull)(j.hubId)),C(n.visible))).orderBy((0,s.desc)(u.id));if(W.length===0)return[];let ae=W.map(X=>X.hub.id),Te=await e.select({hubId:K.hubId,id:V.id,name:V.name,color:V.color}).from(K).innerJoin(V,(0,s.eq)(K.labelId,V.id)).where((0,s.inArray)(K.hubId,ae)),De=await e.select({hubId:h.hubId,id:h.id,body:h.body,createdAt:h.createdAt,userId:h.userId,userName:o.displayName}).from(h).leftJoin(o,(0,s.eq)(h.userId,o.id)).where((0,s.inArray)(h.hubId,ae)).orderBy((0,s.asc)(h.createdAt)),Ae=await Ye(ae),Re=new Map,se=new Map;for(let X of Te){let oe=Re.get(X.hubId);oe||(oe=[],Re.set(X.hubId,oe)),oe.push({id:X.id,name:X.name,color:X.color})}for(let X of De){let oe=se.get(X.hubId);oe||(oe=[],se.set(X.hubId,oe)),oe.push({id:X.id,content:X.body,createdAt:re(X.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:X.userId,userName:X.userName||""})}return W.map(X=>{let oe=X.hub.id;return he(n,{...X,attachments:Ae.get(oe)??[],labels:Re.get(oe)||[],postedCommentRows:se.get(oe)||[]},R)})},forceRefresh:p,snapshot:b,ttlMsOverride:g??E,epochKey:`${A}${T}`})},Ne=async(n,a,i,{forceRefresh:p=!1,snapshot:b=!1,ttlMsOverride:g}={})=>{if(we(n.visible))return null;let R=M(a,i,xe(n));return(await y.getOrFetch({cacheKey:R,fetcher:async()=>{let _=await ge(),Q=(0,s.aliasedTable)(K,"draft_label"),j=await Z(e.select({hub:Se(u),internal:Se(Y),isRead:F.isRead,isStarred:F.isStarred,creatorName:o.displayName,...O()}).from(u)).leftJoin(Y,(0,s.eq)(u.id,Y.hubId)).leftJoin(F,(0,s.and)((0,s.eq)(u.id,F.hubId),(0,s.eq)(F.userId,i))).leftJoin(Q,(0,s.and)((0,s.eq)(Q.hubId,u.id),(0,s.inArray)(Q.labelId,_))).leftJoin(o,(0,s.eq)(u.userId,o.id)).where((0,s.and)((0,s.eq)(u.id,a),(0,s.isNull)(u.deletedAt),(0,s.or)((0,s.eq)(u.userId,i),(0,s.isNull)(Q.hubId)),C(n.visible)));if(j.length===0)return[];let W=j[0].hub.id,ae=await e.select({id:V.id,name:V.name,color:V.color}).from(K).innerJoin(V,(0,s.eq)(K.labelId,V.id)).where((0,s.eq)(K.hubId,W)),Te=await e.select({id:h.id,body:h.body,createdAt:h.createdAt,userId:h.userId,userName:o.displayName}).from(h).leftJoin(o,(0,s.eq)(h.userId,o.id)).where((0,s.eq)(h.hubId,W)).orderBy((0,s.asc)(h.createdAt)),De=await Ye([W]),Ae=ae.map(se=>({id:se.id,name:se.name,color:se.color})),Re=Te.map(se=>({id:se.id,content:se.body,createdAt:re(se.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:se.userId,userName:se.userName||""}));return[he(n,{...j[0],attachments:De.get(W)??[],labels:Ae,postedCommentRows:Re},i)]},forceRefresh:p,snapshot:b,ttlMsOverride:g??E,epochKey:`${f}${a}`}))[0]??null},Kt=async(n,a,i,p={})=>{let b=await J(i);return b?Ne(n,a,b,p):null},jt=async(n,a)=>{let i=await ge(),p=(0,s.aliasedTable)(K,"draft_label"),[b]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt}).top(1).from(u).leftJoin(p,(0,s.and)((0,s.eq)(p.hubId,u.id),(0,s.inArray)(p.labelId,i))).where((0,s.and)((0,s.eq)(u.id,n),(0,s.or)((0,s.eq)(u.userId,a),(0,s.isNull)(p.hubId))));return b??null},Xe=async(n,a,i)=>{let p=await jt(a,i);if(!p||p.deletedAt||!be(n.visible,p.sourceType))throw new Error("Not Found")},Jt=async(n,a,i,p,b,g)=>{await Xe(n,i,a);let R=await e.select().top(1).from(F).where((0,s.and)((0,s.eq)(F.hubId,i),(0,s.eq)(F.userId,a))),T;if(R.length>0?R[0].isStarred!==b?T=(await e.update(F).set({isStarred:b,updatedAt:new Date,updatedBy:String(a)}).output().where((0,s.and)((0,s.eq)(F.hubId,i),(0,s.eq)(F.userId,a))))[0]:T=R[0]:T=(await e.insert(F).output().values({hubId:i,userId:a,isStarred:b,isRead:!1,createdAt:new Date,createdBy:String(a),updatedAt:new Date,updatedBy:String(a)}))[0],p){let _=ie(p);_&&(y.invalidatePrefix(N(_,a)),await I(`${A}${_}`))}return y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix($(i,a)),await I(`${f}${i}`),await L(ze.parse({type:"status-update",reportHubId:i,recipientRawUserId:a,statusType:"star",value:b,clientTempId:g}),"setStarStatus"),T},Gt=async(n,a,i,p,b,g)=>{await Xe(n,i,a);let R=await e.select().top(1).from(F).where((0,s.and)((0,s.eq)(F.hubId,i),(0,s.eq)(F.userId,a))),T;if(R.length>0?R[0].isRead!==b?T=(await e.update(F).set({isRead:b,updatedAt:new Date,updatedBy:String(a)}).output().where((0,s.and)((0,s.eq)(F.hubId,i),(0,s.eq)(F.userId,a))))[0]:T=R[0]:T=(await e.insert(F).output().values({hubId:i,userId:a,isRead:b,isStarred:!1,createdAt:new Date,createdBy:String(a),updatedAt:new Date,updatedBy:String(a)}))[0],p){let _=ie(p);_&&(y.invalidatePrefix(N(_,a)),await I(`${A}${_}`))}return y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix($(i,a)),await I(`${f}${i}`),await L(ze.parse({type:"status-update",reportHubId:i,recipientRawUserId:a,statusType:"read",value:b,clientTempId:g}),"setReadStatus"),T},Dt=async(n,a)=>{if(a===null)return;let i=await ge(),[p]=await e.select({hubId:K.hubId}).top(1).from(K).where((0,s.and)((0,s.eq)(K.hubId,n),(0,s.inArray)(K.labelId,i)));return p?a:void 0},Qt=async(n,a,i,p,b,g)=>{let[R]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt,userId:u.userId}).top(1).from(u).where((0,s.eq)(u.id,i));if(!R||R.deletedAt)throw new Error("Not Found");if(await Xe(n,i,a),!be(n.commentable,R.sourceType))throw new Error("Comments are restricted by the viewer's comment permission");if(R.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let T=await Dt(i,R.userId),[_]=await e.insert(h).output().values({hubId:i,userId:a,body:p,createdAt:new Date,createdBy:String(a),updatedAt:new Date,updatedBy:String(a)}),[Q]=await e.select({displayName:o.displayName}).top(1).from(o).where((0,s.eq)(o.id,a)),j=Q?.displayName??"Unknown";if(b){let ae=ie(b);ae&&(y.invalidatePrefix(`daily-report:date:${ae}:user:`),await I(`${A}${ae}`))}y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(`daily-report:detail:${i}:user:`),await I(`${f}${i}`);let W={id:_.id,userId:c(_.userId),userName:j,content:_.body,createdAt:re(_.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await L(it.parse({type:"comment-add",reportHubId:i,comment:W,clientTempId:g,recipientRawUserId:T,sourceType:R.sourceType}),"addComment"),W},Xt=async(n,a)=>await n.select().top(1).from(h).where((0,s.eq)(h.id,a)),Wt=async(n,a,i,p,b,g)=>{let R=await Xt(e,p);if(R.length===0)throw new Error("Not Found");if(R[0].hubId!==i)throw new Error("Not Found");let[T]=await e.select({userId:u.userId,sourceType:u.sourceType}).top(1).from(u).where((0,s.eq)(u.id,R[0].hubId));if(!(T&&be(n.visible,T.sourceType)))throw new Error("Not Found");if(R[0].userId!==a)throw new Error("Unauthorized");let _=await Dt(i,T.userId);if(await e.delete(h).where((0,s.eq)(h.id,p)),b){let Q=ie(b);Q&&(y.invalidatePrefix(`daily-report:date:${Q}:user:`),await I(`${A}${Q}`))}y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(`daily-report:detail:${i}:user:`),await I(`${f}${i}`),await L(lt.parse({type:"comment-delete",reportHubId:i,commentId:p,clientTempId:g,recipientRawUserId:_,sourceType:T?.sourceType}),"deleteComment")},Zt=async(n,a,i)=>{te.info("createDailyReport called",{userId:n,businessDate:a});let[p]=await e.select({displayName:o.displayName}).from(o).where((0,s.eq)(o.id,n)),b=p?.displayName??c(n);try{let g=await Je(async _=>{te.info("Starting transaction");let Q=`internal-temp-${Date.now()}-${Math.random()}`,[j]=await _.insert(u).output().values({sourceType:"Internal",sourceId:Q,businessDate:new Date(a),userId:n,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)});await _.update(u).set({sourceId:String(j.id)}).where((0,s.eq)(u.id,j.id)),te.info("Hub created",j),await _.insert(Y).values({hubId:j.id,body:"",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)}),te.info("Internal created"),te.info("Calling getDraftLabelId");let W=await Qe();te.info("draftLabelId",W);let ae=[];return W&&(await _.insert(K).values({hubId:j.id,labelId:W,createdAt:new Date,createdBy:String(n)}),ae.push({id:W,name:Ee,color:null})),te.info("Label assigned"),{reportHubId:j.id,date:a,createdAt:re(j.createdAt,"YYYY-MM-DD HH:mm:ss"),author:b,userId:c(n),sourceType:"Internal",employeeName:b,updatedBy:c(n),updatedAt:re(j.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:j.title,content:"",externalComments:[],isRead:!0,isStarred:!1,labels:ae,postedComments:[],attachments:[]}}),R=ie(a);R&&y.invalidatePrefix(N(R,n)),y.invalidatePrefix(H),y.invalidatePrefix(ce(n)),await I(S),R&&await I(`${A}${R}`);let T=await Ne(me.unrestricted("post-write self read: the writer always sees the row they just wrote"),g.reportHubId,n,{forceRefresh:!0});if(T){let _=await Me(),Q=T.labels.some(j=>_.includes(j.id));await L(ut.parse({type:"report-create",reportHubId:T.reportHubId,report:T,clientTempId:i,recipientRawUserId:Q?n:void 0}),"createDailyReport")}return T??g}catch(g){throw te.error("Error in createDailyReport",g),g}},Fe=async(n,a)=>await n.select().top(1).from(u).where((0,s.eq)(u.id,a)),We=async(n,a,i)=>{await n.update(u).set(i).where((0,s.eq)(u.id,a))},wt=async(n,a,i)=>{await n.update(Y).set(i).where((0,s.eq)(Y.hubId,a))},St=async(n,a,i)=>{await n.delete(K).where((0,s.and)((0,s.eq)(K.hubId,a),(0,s.eq)(K.labelId,i)))};return{streamKey:q,streamMaxLen:v,clearCache:async()=>{y.clearAll(),x.clear(),fe=null,k&&await I(S),te.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(n,a)=>{y.invalidatePrefix(H),y.invalidatePrefix(Ie),await I(S);for(let i of new Set(n))y.invalidatePrefix(`daily-report:detail:${i}:user:`),await I(`${f}${i}`);for(let i of new Set(a)){let p=ie(i);p&&await I(`${A}${p}`)}},getUserIdByExternalId:J,getDailyReportIdsByExternalId:ue,getDailyReportIdsFirstPageByExternalId:ne,getDailyReportsByBusinessDate:Ge,getDailyReportsByBusinessDateByExternalId:Vt,getDailyReportDetailById:Ne,getDailyReportDetailByIdByExternalId:Kt,getDraftLabelId:Qe,getAttachmentsByHubIds:Ye,getAttachmentForUser:Ft,markAttachmentMissing:qt,markAttachmentPresent:zt,setStarStatus:Jt,setReadStatus:Gt,addComment:Qt,deleteComment:Wt,createDailyReport:Zt,updateDailyReport:async(n,a,i,p)=>{let b=await Fe(e,n);if(!b.length||b[0].deletedAt)throw new Error("Not Found");if(b[0].userId!==a)throw new Error("Unauthorized");await Je(async T=>{i.title!==void 0&&await We(T,n,{title:i.title,updatedAt:new Date,updatedBy:String(a)}),i.content!==void 0&&await wt(T,n,{body:i.content,updatedAt:new Date,updatedBy:String(a)})}),y.invalidate(`daily-report:detail:${n}`),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(H),await I(`${f}${n}`);let g=ie(re(b[0].businessDate,"YYYY-MM-DD"));g&&(y.invalidatePrefix(`daily-report:date:${g}:user:`),await I(`${A}${g}`));let R=await Ne(me.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,a,{forceRefresh:!0});if(R){let T=await Me(),_=R.labels.some(Q=>T.includes(Q.id));await L(dt.parse({type:"report-update",reportHubId:R.reportHubId,report:R,clientTempId:p,recipientRawUserId:_?a:void 0}),"updateDailyReport")}},publishDailyReport:async(n,a,i)=>{let p=await Fe(e,n);if(!p.length)throw new Error("Not Found");if(p[0].userId!==a)throw new Error("Unauthorized");let b=await Qe();if(!b)return null;if(await St(e,n,b),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(H),y.invalidatePrefix(Ie),await I(S),p[0].businessDate){let T=ie(re(p[0].businessDate,"YYYY-MM-DD"));T&&await I(`${A}${T}`)}let g=ie(re(p[0].businessDate,"YYYY-MM-DD"));g&&y.invalidatePrefix(N(g,a));let R=await Ne(me.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,a,{forceRefresh:!0});return R&&await L(ct.parse({type:"report-publish",reportHubId:R.reportHubId,report:R,clientTempId:i}),"publishDailyReport"),R??null},deleteDailyReport:async(n,a,i)=>{let p=await Fe(e,n);if(!p.length||p[0].deletedAt)throw new Error("Not Found");if(p[0].userId!==a)throw new Error("Unauthorized");if(await We(e,n,{deletedAt:new Date,deletedBy:String(a),updatedAt:new Date,updatedBy:String(a)}),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(H),y.invalidatePrefix(Ie),await I(S),p[0].businessDate){let b=ie(re(p[0].businessDate,"YYYY-MM-DD"));b&&await I(`${A}${b}`)}await L(pt.parse({type:"report-delete",reportHubId:n,clientTempId:i,sourceType:p[0].sourceType}),"deleteDailyReport")},findDailyReportHubById:Fe,updateDailyReportHub:We,updateDailyReportInternal:wt,deleteDailyReportLabel:St}}var He=require("drizzle-orm");function Ot(t){let e=[],r=t&&t.length>0?t:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let o of r){let c=`daily_report_${o.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:c,name:o.name,description:o.description??`${o.name} daily report access`}),o.includeCommentResource!==!1&&e.push({resourceKey:`${c}_comment`,name:`${o.name} Comment`,description:`${o.name} daily report comment access`})}return e}async function qr(t,e,r){let o=t,d=e.TMResource,c=r.appKey,D=r.actor??"system:daily-report",y=new Date,k=r.resources??Ot(r.sources);for(let u of k){let Y=await o.select().from(d).where((0,He.and)((0,He.eq)(d.appKey,c),(0,He.eq)(d.resourceKey,u.resourceKey)));(!Y||Y.length===0)&&await o.insert(d).values({appKey:c,resourceKey:u.resourceKey,name:u.name,description:u.description??null,createdAt:y,createdBy:D,updatedAt:y,updatedBy:D})}}var zr=de(1,"[DailyReportExternalSource]"),Vr=(t,e,r,o=zr)=>{if(!t)return[];try{let d=JSON.parse(t);return Array.isArray(d)?d.map(r).filter(c=>c!==null):(o.warn(`Unexpected ${e} format: not an array`),[])}catch(d){return o.warn(`Failed to parse ${e}:`,d),[]}};var Oe=require("drizzle-orm"),l=require("drizzle-orm/mssql-core");function Kr(t,e){let r=(0,l.mssqlSchema)(t),o=e.userTable,d=r.table("DailyReportHub",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,l.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,l.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,l.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(Oe.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,l.date)("business_date"),userId:(0,l.bigint)("user_id",{mode:"number"}),title:(0,l.nvarchar)("title",{length:200}),summary:(0,l.nvarchar)("summary",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,l.datetime2)("deleted_at"),deletedBy:(0,l.nvarchar)("deleted_by",{length:50})},h=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_user_id_fk`,columns:[h.userId],foreignColumns:[o.id]}),(0,l.index)(`${t}_DailyReportHub_business_date_index`).on(h.businessDate),(0,l.index)(`${t}_DailyReportHub_updated_at_index`).on(h.updatedAt),(0,l.index)(`${t}_DailyReportHub_source_index`).on(h.sourceType,h.sourceId),(0,l.index)(`${t}_DailyReportHub_user_id_index`).on(h.userId),(0,l.index)(`${t}_DailyReportHub_business_date_id_index`).on((0,Oe.desc)(h.businessDate),(0,Oe.desc)(h.id)),(0,l.index)(`${t}_DailyReportHub_deleted_at_index`).on(h.deletedAt)]),c=r.table("DailyReportInternal",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}),metadata:(0,l.nvarchar)("metadata",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportInternal_pk`,columns:[h.hubId]}),(0,l.foreignKey)({name:`${t}_DailyReportInternal_hub_id_fk`,columns:[h.hubId],foreignColumns:[d.id]})]),D=r.table("DailyReportComment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportComment_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_hub_id_fk`,columns:[h.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_user_id_fk`,columns:[h.userId],foreignColumns:[o.id]}),(0,l.index)(`${t}_DailyReportComment_hub_id_index`).on(h.hubId)]),y=r.table("DailyReportLabel",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}),name:(0,l.nvarchar)("name",{length:50}).notNull(),color:(0,l.nvarchar)("color",{length:20}),sortOrder:(0,l.int)("sort_order"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportLabel_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportLabel_user_id_fk`,columns:[h.userId],foreignColumns:[o.id]})]),k=r.table("DailyReportHub_Label",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,l.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_Label_pk`,columns:[h.hubId,h.labelId]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_hub_id_fk`,columns:[h.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_label_id_fk`,columns:[h.labelId],foreignColumns:[y.id]})]),u=r.table("DailyReportUserStatus",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,l.bit)("is_read").default(!1).notNull(),isStarred:(0,l.bit)("is_starred").default(!1).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportUserStatus_pk`,columns:[h.hubId,h.userId]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_hub_id_fk`,columns:[h.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_user_id_fk`,columns:[h.userId],foreignColumns:[o.id]})]),Y=r.table("DailyReportAttachment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),uploadedBy:(0,l.bigint)("uploaded_by",{mode:"number"}),sourceKey:(0,l.nvarchar)("source_key",{length:200}).notNull(),fileName:(0,l.nvarchar)("file_name",{length:255}).notNull(),filePath:(0,l.nvarchar)("file_path",{length:"max"}).notNull(),fileType:(0,l.nvarchar)("file_type",{length:100}),fileSize:(0,l.bigint)("file_size",{mode:"number"}),objectCheckedAt:(0,l.datetime2)("object_checked_at"),objectMissingAt:(0,l.datetime2)("object_missing_at"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportAttachment_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_hub_id_fk`,columns:[h.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_uploaded_by_fk`,columns:[h.uploadedBy],foreignColumns:[o.id]}),(0,l.uniqueIndex)(`${t}_DailyReportAttachment_source_unique`).on(h.hubId,h.sourceKey),(0,l.index)(`${t}_DailyReportAttachment_hub_id_index`).on(h.hubId,h.createdAt)]);return{hub:d,internal:c,comment:D,attachment:Y,label:y,hubLabel:k,userStatus:u}}function jr(t){t.redis||(t.logger??console).warn("[DailyReport] redis provider is not injected: cross-worker cache invalidation is disabled (staleness is bounded only by TTL) and SSE publishing is skipped.");let e=nt(t.redis),r=new Pe({defaultTtlMs:t.cacheDefaultTtlMs??6e4},e),o=gt({...t,cache:r,epochs:e}),d=new $e({redis:t.redis,streamKey:o.streamKey,cache:r,logger:t.logger}),c=bt({authenticate:t.authenticate,resolveVisibleSourceTypes:t.resolveVisibleSourceTypes,service:o,encodeUserId:t.encodeUserId,attachmentIdCodec:t.attachmentIdCodec,readAttachment:t.readAttachment,attachmentMaxBytes:t.attachmentMaxBytes,attachmentRateLimitPerMinute:t.attachmentRateLimitPerMinute,attachmentConcurrency:t.attachmentConcurrency,redis:t.redis,sseReader:d,streamKey:o.streamKey,loginRedirectPath:t.loginRedirectPath,enableDevCacheClear:t.enableDevCacheClear,logger:t.logger});return{service:o,cache:r,epochs:e,sseReader:d,streamKey:o.streamKey,knownSourceTypes:[...new Set(["Internal",...(t.externalSources??[]).map(D=>D.sourceType)])],...c}}0&&(module.exports={DailyReportSseReader,DailyReportViewerScope,SqlResultCache,asciiFallbackFileName,buildVisibleSourceTypeCondition,computeSourceTypeDigest,computeViewerScopeDigest,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,deniesEverySourceType,encodeRfc8187,formatDateValue,generateETag,isSourceTypeVisible,isStreamIdLte,jsonResponseWithETag,normalizeVisibleSourceTypes,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
|
|
1
|
+
"use strict";var nt=Object.defineProperty;var cr=Object.getOwnPropertyDescriptor;var pr=Object.getOwnPropertyNames;var mr=Object.prototype.hasOwnProperty;var _t=t=>{throw TypeError(t)};var yr=(t,e)=>{for(var r in e)nt(t,r,{get:e[r],enumerable:!0})},hr=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let d of pr(e))!mr.call(t,d)&&d!==r&&nt(t,d,{get:()=>e[d],enumerable:!(s=cr(e,d))||s.enumerable});return t};var fr=t=>hr(nt({},"__esModule",{value:!0}),t);var Ct=(t,e,r)=>e.has(t)||_t("Cannot "+r);var Pe=(t,e,r)=>(Ct(t,e,"read from private field"),r?r.call(t):e.get(t)),at=(t,e,r)=>e.has(t)?_t("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),st=(t,e,r,s)=>(Ct(t,e,"write to private field"),s?s.call(t,r):e.set(t,r),r);var on={};yr(on,{DAILY_REPORT_SSE_CATCH_UP_BATCH:()=>Rt,DAILY_REPORT_SSE_VISIBILITY_REFRESH_MS:()=>jt,DailyReportSseReader:()=>$e,DailyReportViewerScope:()=>ue,SqlResultCache:()=>Le,asciiFallbackFileName:()=>Gt,buildVisibleSourceTypeCondition:()=>gt,computeSourceTypeDigest:()=>bt,computeViewerScopeDigest:()=>xe,createDailyReportHandlers:()=>Dt,createDailyReportServer:()=>sn,createDailyReportService:()=>wt,createEpochStore:()=>ot,defineDailyReportAuthzResources:()=>Wt,defineDailyReportSchema:()=>an,deniesEverySourceType:()=>be,encodeRfc8187:()=>Jt,formatDateValue:()=>ee,generateETag:()=>Ge,isSourceTypeVisible:()=>ce,isStreamIdLte:()=>Ie,jsonResponseWithETag:()=>le,normalizeVisibleSourceTypes:()=>ft,sanitizeMediaType:()=>St,seedDailyReportAuthzResources:()=>tn,transformJsonArray:()=>nn});module.exports=fr(on);var ot=t=>({async getEpoch(e){try{let r=await t?.getClient();if(!r)return null;let s=await r.get(e);return s?Number(s):0}catch{return null}},async incrementEpoch(e){try{let r=await t?.getClient();if(!r)return;await r.incr(e)}catch{}}}),Le=class{constructor(e,r){this.config=e;this.epochStore=r;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.maybeRefreshAhead=e=>{let r=e.refreshAheadRatio;if(r===void 0)return;let{cacheKey:s}=e,d=this.buckets.get(s);if(!d)return;let c=e.ttlMsOverride??this.config.defaultTtlMs;if(c-(d.expireAt-Date.now())<c*r||this.inFlight.has(s))return;let y;y=(async()=>{let L=e.epochKey?await this.epochStore.getEpoch(e.epochKey):null,u=await e.fetcher();return this.inFlight.get(s)===y&&this.buckets.set(s,{records:u,expireAt:Date.now()+c,epoch:L}),u})(),this.inFlight.set(s,y),y.catch(()=>{}).finally(()=>{this.inFlight.get(s)===y&&this.inFlight.delete(s)})};this.getOrFetch=async e=>{let{cacheKey:r,forceRefresh:s,snapshot:d}=e,c=this.buckets.get(r);if(s&&(this.buckets.delete(r),this.inFlight.delete(r)),!s&&c&&c.expireAt>Date.now())if(e.epochKey){let y=await this.epochStore.getEpoch(e.epochKey);if(y===null||c.epoch===y)return this.maybeRefreshAhead(e),d?c.records.map(L=>structuredClone(L)):c.records;this.buckets.delete(r)}else return this.maybeRefreshAhead(e),d?c.records.map(y=>structuredClone(y)):c.records;if(!s&&this.inFlight.has(r)){let y=await this.inFlight.get(r);return d?y.map(L=>structuredClone(L)):y}let D;D=(async()=>{let y=e.epochKey?await this.epochStore.getEpoch(e.epochKey):null;e.onFetchStart?.();let L=await e.fetcher();if(s||this.inFlight.get(r)===D){let u=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs);this.buckets.set(r,{records:L,expireAt:u,epoch:y}),this.buckets.size>500&&this.cleanExpired()}return L})(),s||this.inFlight.set(r,D);try{let y=await D;return d?y.map(L=>structuredClone(L)):y}finally{this.inFlight.get(r)===D&&this.inFlight.delete(r)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let r of this.buckets.keys())r.startsWith(e)&&this.buckets.delete(r);for(let r of this.inFlight.keys())r.startsWith(e)&&this.inFlight.delete(r)}}cleanExpired(){let e=Date.now();for(let[r,s]of this.buckets.entries())s.expireAt<=e&&this.buckets.delete(r)}};var zt=require("@aiquants/sse"),ge=require("@aiquants/sse/server");var br=/^\d{4}-\d{2}-\d{2}$/,gr=/^\d{4}\/\d{2}\/\d{2}$/,Et=t=>t<10?`0${t}`:`${t}`,vt=t=>{if(Number.isNaN(t.getTime()))return null;let e=t.getFullYear(),r=Et(t.getMonth()+1),s=Et(t.getDate());return`${e}-${r}-${s}`};var ae=t=>{if(t==null)return null;if(t instanceof Date)return vt(t);let e=t.trim();if(e==="")return null;if(br.test(e))return e;if(gr.test(e))return e.replaceAll("/","-");let r=new Date(e);return vt(r)};var it=t=>{let e=2166136261,r=-624069552;for(let s of t){let d=s.reportHubId;e^=d&255,e=Math.imul(e,16777619),e^=d>>>8&255,e=Math.imul(e,16777619),e^=d>>>16&255,e=Math.imul(e,16777619),e^=d>>>24&255,e=Math.imul(e,16777619),r^=d>>>24&255,r=Math.imul(r,16777619),r^=d>>>16&255,r=Math.imul(r,16777619),r^=d>>>8&255,r=Math.imul(r,16777619),r^=d&255,r=Math.imul(r,16777619);let c=s.businessDate;if(c===null)e^=1,e=Math.imul(e,16777619),r^=1,r=Math.imul(r,16777619);else for(let D=0;D<c.length;D++){let y=c.charCodeAt(D);e^=y&255,e=Math.imul(e,16777619),r^=y&255,r=Math.imul(r,16777619)}}return e^=t.length,e=Math.imul(e,16777619),r^=t.length,r=Math.imul(r,16777619),((e>>>0).toString(16).padStart(8,"0")+(r>>>0).toString(16).padStart(8,"0")).replace(/^0+(?=.)/,"")},je=(t,e)=>t.businessDate!==e.businessDate?t.businessDate===null?1:e.businessDate===null||t.businessDate>e.businessDate?-1:1:e.reportHubId-t.reportHubId,xt=t=>{for(let e=1;e<t.length;e++)if(je(t[e-1],t[e])>0)return!1;return!0};var Mt=(t,e)=>{let r=t.findIndex(s=>je({businessDate:s.businessDate,reportHubId:s.reportHubId},e)>0);return r===-1?t.length:r};var oe=(t,e,r=console)=>{let s=d=>typeof d=="string"?[`${e} ${d}`]:[e,d];return{debug:(d,...c)=>{t<=0&&r.debug(...s(d),...c)},info:(d,...c)=>{t<=1&&r.info(...s(d),...c)},warn:(d,...c)=>{t<=2&&r.warn(...s(d),...c)},error:(d,...c)=>{t<=3&&r.error(...s(d),...c)}}};var m=require("zod");var kt=15e3,Nt="lastEventId",Rr=/^\d{1,15}-\d{1,15}$/,Pt=t=>Rr.test(t),Sr=m.z.object({name:m.z.string().nullish(),affiliation:m.z.string().nullish()}),Dr=m.z.object({name:m.z.string().nullish(),text:m.z.string().nullish(),color:m.z.string().nullish()}),wr=m.z.object({id:m.z.number(),name:m.z.string().nullish(),color:m.z.string().nullish()}),Lt=m.z.object({id:m.z.number(),userId:m.z.string().nullish(),userName:m.z.string().nullish(),content:m.z.string().nullish(),createdAt:m.z.string().nullish(),isMine:m.z.boolean()}),Ir=m.z.object({id:m.z.string(),fileName:m.z.string(),fileType:m.z.string().nullable(),fileSize:m.z.number().nullable(),createdAt:m.z.string().nullable(),state:m.z.enum(["present","absent","unknown"])}),lt=m.z.object({reportHubId:m.z.number(),date:m.z.string().nullish(),createdAt:m.z.string().nullish(),author:m.z.string().nullish(),userId:m.z.string().nullish(),sourceType:m.z.string().nullish(),employeeName:m.z.string().nullish(),updatedBy:m.z.string().nullish(),updatedAt:m.z.string().nullish(),category:m.z.string().nullish(),creationCategory:m.z.string().nullish(),visitTimeFrom:m.z.string().nullish(),visitTimeTo:m.z.string().nullish(),customerName:m.z.string().nullish(),interviewers:m.z.array(Sr),subject:m.z.string().nullish(),content:m.z.string().nullish(),externalComments:m.z.array(Dr),isRead:m.z.boolean(),isStarred:m.z.boolean(),labels:m.z.array(wr),postedComments:m.z.array(Lt),attachments:m.z.array(Ir).default([])}),Ar=m.z.object({type:m.z.literal("connected")}),Je=m.z.object({type:m.z.literal("status-update"),reportHubId:m.z.number(),statusType:m.z.enum(["star","read"]),value:m.z.boolean(),clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),ut=m.z.string().optional(),dt=m.z.object({type:m.z.literal("comment-add"),reportHubId:m.z.number(),comment:Lt,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional(),sourceType:ut}),ct=m.z.object({type:m.z.literal("comment-delete"),reportHubId:m.z.number(),commentId:m.z.number(),clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional(),sourceType:ut}),pt=m.z.object({type:m.z.literal("report-create"),reportHubId:m.z.number(),report:lt,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),mt=m.z.object({type:m.z.literal("report-update"),reportHubId:m.z.number(),report:lt,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),yt=m.z.object({type:m.z.literal("report-publish"),reportHubId:m.z.number(),report:lt,clientTempId:m.z.string(),recipientRawUserId:m.z.number().optional()}),ht=m.z.object({type:m.z.literal("report-delete"),reportHubId:m.z.number(),clientTempId:m.z.string(),sourceType:ut}),$t=m.z.discriminatedUnion("type",[Ar,Je,dt,ct,pt,mt,yt,ht]);var Bt=require("crypto"),Ge=t=>{let e=JSON.stringify(t);return`"${(0,Bt.createHash)("sha256").update(e).digest("hex")}"`};var Tr=oe(1,"[Response]"),le=(t,e,r,s=200,d=Tr)=>{let c=Ge(r),D=t.headers.get("If-None-Match");d.info(`[jsonResponseWithETag] ETag: ${c}, If-None-Match: ${D}`);let y=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:c});return e&&y.append("Set-Cookie",e),t.method==="GET"&&s===200&&D===c?new Response(null,{status:304,headers:y}):new Response(JSON.stringify(r),{status:s,headers:y})};var Ut=require("events");var Ie=(t,e)=>{let[r,s]=t.split("-").map(Number),[d,c]=e.split("-").map(Number);return r!==d?r<d:s<=c},$e=class{constructor(e){this.config=e;this._emitter=new Ut.EventEmitter;this._state="idle";this._refCount=0;this._lastId="$";this._emitter.setMaxListeners(0),this._logger=e.logger??oe(1,"[SSE Reader]")}subscribe(e,r){return this._emitter.on("entry",e),r&&this._emitter.on("error",r),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),r&&this._emitter.removeListener("error",r),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="$"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"&&this._refCount!==0){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitError(e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitError(new Error("Failed to create Redis client for SSE reader"));return}if(this._client.on("error",e=>{this._logger.error("Redis client error:",e)}),this._lastId==="$")try{let e=await this.config.redis?.getClient();if(e){let r=await e.xRevRange(this.config.streamKey,"+","-",{COUNT:1});this._lastId=r.length>0?r[0].id:"0-0"}}catch(e){this._logger.warn("Failed to resolve stream tail anchor; falling back to $:",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 r of e)for(let s of r.messages){this._lastId=s.id;try{let d=s.message?.data?JSON.parse(s.message.data):null,c=d?.type;if((c==="report-create"||c==="report-delete"||c==="report-publish")&&this.config.cache.invalidatePrefix("daily-report:ids"),c==="comment-add"||c==="comment-delete"||c==="status-update"){let D=d?.reportHubId;typeof D=="number"&&(this.config.cache.invalidate(`daily-report:detail:${D}`),this.config.cache.invalidatePrefix(`daily-report:detail:${D}:user:`))}}catch{}this._emitter.emit("entry",{id:s.id,message:s.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitError(e instanceof Error?e:new Error(String(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==="stopping";)await new Promise(e=>setTimeout(e,50))}}_emitError(e){this._emitter.listenerCount("error")>0?this._emitter.emit("error",e):this._logger.error("SSE reader error (no error listeners):",e)}};var Ue=require("drizzle-orm");var _r="",Cr=64,Er=t=>t.toLowerCase(),vr=t=>t.trim().toLowerCase();function ft(t){if(t==null)return null;if(!Array.isArray(t))return new Set;let e=new Set;for(let r of t){if(typeof r!="string")continue;let s=vr(r);s.length>0&&e.add(s)}return e}function ce(t,e){return t===null?!0:e==null?!1:t.has(Er(e))}function be(t){return t!==null&&t.size===0}function gt(t,e){if(e!==null)return e.size===0?Ue.sql`1 = 0`:(0,Ue.inArray)(Ue.sql`LOWER(${t})`,[...e])}var Ee,ve,Be=class Be{constructor(e,r){at(this,Ee);at(this,ve);st(this,Ee,e),st(this,ve,r)}get visible(){return Pe(this,Ee)===null?null:new Set(Pe(this,Ee))}get commentable(){return Pe(this,ve)===null?null:new Set(Pe(this,ve))}static restrictTo(e){let r=typeof e=="object"&&e!==null&&"read"in e,s=ft(r?e.read:e),d=r?e.comment:void 0;if(d===void 0)return new Be(s,s);let c=ft(d),D=new Set;for(let y of c??[])s.has(y)&&D.add(y);return new Be(s,D)}static unrestricted(e){return new Be(null,null)}};Ee=new WeakMap,ve=new WeakMap;var ue=Be;function xe(t){let e=bt(t.visible),r=bt(t.commentable);return e===r?e:`d:${e.length}:${e}${r}`}function bt(t){if(t===null)return"all";if(t.size===0)return"none";let e=[...t].sort().map(s=>`${s.length}:${s}`).join(_r);if(e.length<=Cr)return`s:${e}`;let r=2166136261;for(let s=0;s<e.length;s++)r^=e.charCodeAt(s),r=Math.imul(r,16777619);return`sh:${(r>>>0).toString(16)}`}var xr=(t,e)=>{let r=new Headers({"Content-Type":"application/json"});return e?.setCookie&&r.append("Set-Cookie",e.setCookie),new Response(JSON.stringify(t),{status:e?.status??200,headers:r})},We=30,Kt=4e3,Mr="stream interrupted by server error",kr=/^\d{4}-\d{2}-\d{2}$/,Nr=15e3,Ot=Symbol("ids-stream-heartbeat"),Ht=864e5,Pr={baseMs:2e3,jitterMs:8e3},jt=6e4,Rt=1e3,Yt=JSON.stringify({type:"connected"}),qt="0-0",Lr=/^[0-9a-f]{1,16}$/,$r=t=>{let e=t.searchParams.get("cursor_report_hub_id"),r=t.searchParams.get("cursor_business_date"),s=t.searchParams.get("cursor_snapshot"),d=s!==null&&Lr.test(s)?s:null;if(e===null)return r===null?{cursor:null,snapshot:d}:{invalid:!0};let c=Number.parseInt(e,10);return!Number.isSafeInteger(c)||String(c)!==e||c<=0?{invalid:!0}:r===null?{cursor:{businessDate:null,reportHubId:c},snapshot:d}:kr.test(r)?{cursor:{businessDate:r,reportHubId:c},snapshot:d}:{invalid:!0}};async function*Ft(t,e,r,s){let d=e?Mt(t,e):0,c=!0;for(;;){let D=t.slice(d,d+(c?r:Kt));d+=D.length;let y=d>=t.length,L=D[D.length-1];if(yield{kind:"chunk",items:D,nextCursor:y||!L?null:{businessDate:L.businessDate,reportHubId:L.reportHubId},isLast:y,...c?{total:t.length}:{},...c?{streamAnchor:s.streamAnchor}:{},snapshot:s.snapshot,...c&&s.restarted?{restarted:!0}:{}},c=!1,y)return}}var Vt=(t,e,r,s)=>{let d=new TextEncoder,c=!1,D=null,y=new ReadableStream({async pull(u){if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}let U=null;try{D===null&&(D=e.next());let f=new Promise(de=>{U=setTimeout(()=>de(Ot),Nr)}),V=await Promise.race([D,f]);if(U!==null&&(clearTimeout(U),U=null),V===Ot){if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(d.encode(`
|
|
2
|
+
`));return}D=null;let{value:z,done:Y}=V;if(Y){u.close();return}if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(d.encode(`${JSON.stringify(z)}
|
|
3
|
+
`))}catch(f){if(U!==null&&clearTimeout(U),D=null,c||r.signal.aborted)return;s.error(`ids-stream emission failed: ${f instanceof Error?f.message:String(f)}`);try{let V={kind:"error",error:Mr};u.enqueue(d.encode(`${JSON.stringify(V)}
|
|
4
|
+
`)),u.close()}catch{}}},cancel(){c=!0,e.return(void 0).catch(()=>{})}}),L=new Headers({"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"private, no-cache, no-transform","X-Content-Type-Options":"nosniff"});return t&&L.append("Set-Cookie",t),new Response(y,{status:200,headers:L})},Br=32*1024*1024,Ur=60,Or=4,Hr=12e4,Yr=1024,qr=60,Fr=5,Vr=new Set(["image/png","image/jpeg","image/gif","image/webp","application/pdf","text/plain"]),zr=/^[\x20-\x7E]+$/,Kr=/^[\w.+-]+\/[\w.+-]+/,St=t=>t&&zr.test(t)&&Kr.test(t)?t:null,Jt=t=>encodeURIComponent(t).replace(/['()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`),Gt=t=>t.replace(/[^\x20-\x7E]/g,"_").replace(/["\\]/g,"_"),jr=t=>{switch(t){case"not_found":case"denied":case"invalid_path":return 404;case"too_large":return 413;default:return 502}},Jr={404:"Attachment not found",413:"Attachment too large",502:"Attachment storage unavailable"},Gr=t=>{let e=new Map;return(r,s)=>{let d=e.get(r);d&&e.delete(r);let c=d??{tokens:t,lastRefillMs:s},D=Math.max(0,s-c.lastRefillMs);D>0&&(c.tokens=Math.min(t,c.tokens+D*t/6e4),c.lastRefillMs=s);let y=c.tokens>=1;for(y&&(c.tokens-=1),e.set(r,c);e.size>Yr;){let L=e.keys().next();if(L.done)break;e.delete(L.value)}return y}},Qr=t=>{let e=0;return{tryAcquire:()=>e>=t?!1:(e+=1,!0),release:()=>{e>0&&(e-=1)}}},Wr=(t,e,r)=>{let s=setTimeout(e,r);s.unref?.();let d=()=>{clearTimeout(s),e()},c=!1;return new ReadableStream({pull(D){if(c){D.close(),d();return}c=!0,D.enqueue(t)},cancel(){d()}})},Xr=(t,e,r,s)=>{if(r===null&&s===null)return!0;let d=typeof e.sourceType=="string"?e.sourceType:void 0;switch(t.type){case"connected":case"status-update":return!0;case"report-create":case"report-update":case"report-publish":return ce(r,t.report.sourceType);case"comment-add":case"comment-delete":return ce(s,d??"Internal");case"report-delete":return ce(r,d)}},Zr=["externalComments","postedComments"],en=(t,e,r)=>{if(r===null||t.type!=="report-create"&&t.type!=="report-update"&&t.type!=="report-publish"||ce(r,t.report.sourceType))return!1;let s=e.report;if(typeof s!="object"||s===null)return!1;let d=s;for(let c of Zr)d[c]=[];return!0};function Dt(t){let{authenticate:e,service:r,encodeUserId:s,redis:d,sseReader:c,streamKey:D}=t,y=t.loginRedirectPath??"/auth/login",L=t.logger??oe(3,"[DailyReportAPI]"),u=t.logger??oe(3,"[DailyReportVisibility]"),U=t.logger??oe(1,"[DailyReportSSE]"),f=t.logger??oe(1,"[DailyReportAttachment]"),V=t.attachmentMaxBytes??Br,z=Gr(t.attachmentRateLimitPerMinute??Ur),Y=Qr(t.attachmentConcurrency??Or),de=async(b,M="initial")=>{let k=t.resolveVisibleSourceTypes;if(!k)return ue.unrestricted("no visibility port injected: this deployment does not restrict by source type");try{let I=await k(b,{reason:M});return I==null?ue.unrestricted("visibility port returned null/undefined: this deployment opts out of source-type filtering"):ue.restrictTo(I)}catch(I){return u.error("resolveVisibleSourceTypes threw; failing closed (deny all)",I),ue.restrictTo([])}},Me=async({request:b})=>{let{user:M,cookie:k}=await e(b,{failureRedirect:y}),I=new Headers;k&&I.append("Set-Cookie",k);let h=await r.getUserIdByExternalId(M.id),g=h?s(h):null;return{data:{user:M,userId:g},headers:I}},ke={"business-date":async(b,M,k,I,h)=>{let g=ae(b.searchParams.get("businessDate")),v=b.searchParams.get("forceRefresh")==="true";if(!g)return le(k,M,{error:{message:"Invalid business date"}},400);let E=await r.getDailyReportsByBusinessDateByExternalId(h,g,I.id,{forceRefresh:v});return le(k,M,{businessDate:g,reports:E},200)},"ids-stream":async(b,M,k,I,h)=>{let g=$r(b);if("invalid"in g)return le(k,M,{error:{message:"Invalid cursor"}},400);let v=b.searchParams.get("forceRefresh")==="true",E=!1,O=null,C=null,x=new Promise((N,j)=>{O=N,C=j});x.catch(()=>{});let X=r.getDailyReportIdsByExternalId(h,I.id,{forceRefresh:v,onFetchStart:g.cursor?void 0:()=>{E=!0,r.readSseStreamAnchor().then(N=>r.getDailyReportIdsFirstPageByExternalId(h,I.id,We).then(j=>({items:j,streamAnchor:N}))).then(N=>O?.(N),N=>C?.(N))}});if(X.catch(()=>{}),g.cursor){let{items:N,streamAnchor:j}=await X,H=it(N),q=g.snapshot!==null&&g.snapshot===H;return Vt(M,Ft(N,q?g.cursor:null,We,{snapshot:H,restarted:!q,streamAnchor:j}),k,L)}let $=(async function*(){let N=await Promise.race([X.then(q=>({kind:"full",source:q}),q=>({kind:"full-error",error:q})),x.then(q=>({kind:"page",page:q}),()=>({kind:"page-error"}))]),j=null,H=!1;if(N.kind==="full")j=N.source;else if(N.kind==="page"){let{items:q,streamAnchor:A}=N.page;if(q.length<We){yield{kind:"chunk",items:q,nextCursor:null,isLast:!0,total:q.length,streamAnchor:A};return}yield{kind:"chunk",items:q,nextCursor:null,isLast:!1,provisional:!0},H=!0}else if(N.kind==="full-error"&&E){let q=await x.catch(()=>null);q&&q.items.length>0&&(yield{kind:"chunk",items:q.items,nextCursor:null,isLast:!1,provisional:!0})}j===null&&(j=await X),yield*Ft(j.items,null,H?Kt:We,{snapshot:it(j.items),streamAnchor:j.streamAnchor})})();return Vt(M,$,k,L)},report:async(b,M,k,I,h)=>{let g=b.searchParams.get("reportHubId"),v=b.searchParams.get("forceRefresh")==="true",E=g?Number.parseInt(g,10):NaN;if(!Number.isFinite(E)||E<=0)return le(k,M,{error:{message:"Invalid reportHubId"}},400);let O=await r.getDailyReportDetailByIdByExternalId(h,E,I.id,{snapshot:!0,forceRefresh:v});return O?le(k,M,{report:O},200):le(k,M,{error:{message:"Report not found"}},404)}},W=async({request:b,params:M})=>{let{user:k,cookie:I}=await e(b,{failureRedirect:null}),h=I??null;if(!k)return le(b,h,{error:{message:"Unauthorized"}},401);if(b.method!=="GET")return le(b,h,{error:{message:"Method not allowed"}},405);let g=M.endpoint??"",v=ke[g];if(!v)return le(b,h,{error:{message:"Unknown endpoint"}},404);let E=Date.now();try{let O=new URL(b.url),C=await de(b);return await v(O,h,b,k,C)}catch(O){let C=Date.now()-E,x=O instanceof Error?O:new Error(String(O));return L.error(`500 endpoint=${g} elapsed=${C}ms name=${x.name} code=${"code"in x?x.code:"N/A"} message=${x.message}`),L.error("Stack:",x.stack),le(b,h,{error:{message:"Internal Server Error"}},500)}},Ye=async({request:b,params:M})=>{let{user:k,cookie:I}=await e(b,{failureRedirect:null}),h=(v,E)=>xr(v,{...E,setCookie:I});if(!k)return h({error:"Unauthorized"},{status:401});let g=Date.now();try{if(M.endpoint!=="action")return h({error:"Unknown endpoint"},{status:404});let E=await r.getUserIdByExternalId(k.id);if(!E)return h({error:"User not found"},{status:404});let O=await de(b),C=await b.formData(),x=C.get("intent"),X=C.get("reportHubId"),$=X?Number(X):NaN,N=C.get("businessDate"),j=Number(C.get("operationTimestamp")),H=C.get("clientTempId");if(x==="clearCache")return t.enableDevCacheClear?(await r.clearCache(),h({status:"OK",intent:"clearCache"})):h({error:"Invalid intent"},{status:400});if(!H)return h({error:"clientTempId required"},{status:400});if(x!=="create"&&(!$||Number.isNaN($)))return h({error:"Invalid reportHubId"},{status:400});let q=async(A,T,K)=>{let se=C.get(T);if(se===null)return h({error:`${T} required`},{status:400});try{let Z=await K(se==="true");return h({status:"OK",intent:A,updatedStatus:{isStarred:Z.isStarred,isRead:Z.isRead},operationTimestamp:j,reportHubId:String($),clientTempId:H})}catch(Z){if(Z instanceof Error&&Z.message==="Not Found")return h({error:"Report not found"},{status:404});throw Z}};switch(x){case"create":{if(!N)return h({error:"businessDate required"},{status:400});let A=await r.createDailyReport(E,N,H);return h({status:"OK",intent:"create",report:A,reportHubId:String(A.reportHubId),clientTempId:H})}case"update":{let A=C.get("title"),T=C.get("content");try{return await r.updateDailyReport($,E,{title:A,content:T},H),h({status:"OK",intent:"update",reportHubId:String($),clientTempId:H})}catch(K){if(K instanceof Error){if(K.message==="Unauthorized")return h({error:"Unauthorized"},{status:403});if(K.message==="Not Found")return h({error:"Report not found"},{status:404})}throw K}}case"publish":try{let A=await r.publishDailyReport($,E,H);return h({status:"OK",intent:"publish",reportHubId:String($),clientTempId:H,report:A})}catch(A){if(A instanceof Error){if(A.message==="Unauthorized")return h({error:"Unauthorized"},{status:403});if(A.message==="Not Found")return h({error:"Report not found"},{status:404})}throw A}case"delete":try{return await r.deleteDailyReport($,E,H),h({status:"OK",intent:"delete",reportHubId:String($),clientTempId:H})}catch(A){if(A instanceof Error){if(A.message==="Unauthorized")return h({error:"Unauthorized"},{status:403});if(A.message==="Not Found")return h({error:"Report not found"},{status:404})}throw A}case"toggleStar":return await q("toggleStar","isStarred",A=>r.setStarStatus(O,E,$,N,A,H));case"toggleRead":return await q("toggleRead","isRead",A=>r.setReadStatus(O,E,$,N,A,H));case"addComment":{let A=C.get("content");if(!A)return h({error:"Content required"},{status:400});try{let T=await r.addComment(O,E,$,A,N,H),K={...T,userId:T.userId};return h({status:"OK",intent:"addComment",newComment:K,reportHubId:String($),clientTempId:H})}catch(T){if(T instanceof Error){if(T.message==="Not Found")return h({error:"Report not found"},{status:404});if(T.message.startsWith("Comments are restricted"))return h({error:"Comments are restricted for this report"},{status:403})}throw T}}case"deleteComment":{let A=Number(C.get("commentId"));if(!A||Number.isNaN(A))return h({error:"Invalid commentId"},{status:400});try{return await r.deleteComment(O,E,$,A,N,H),h({status:"OK",reportHubId:String($),deletedCommentId:String(A),clientTempId:H})}catch(T){if(T instanceof Error){if(T.message==="Unauthorized")return h({error:"Unauthorized"},{status:403});if(T.message==="Not Found")return h({error:"Comment not found"},{status:404})}throw T}}default:return h({error:"Invalid intent"},{status:400})}}catch(v){if(v instanceof Response)throw v;let E=Date.now()-g,O=v instanceof Error?v:new Error(String(v));return L.error(`500 action elapsed=${E}ms name=${O.name} message=${O.message}`),L.error("Stack:",O.stack),h({error:"Internal Server Error"},{status:500})}},Re=(b,M)=>{b.writeEvent({event:null,id:M,data:Yt})},Xe=(b,M,k,I)=>{if(k.data)try{let h=JSON.parse(k.data),g=$t.safeParse(h);if(!g.success){U.error("SSE message validation failed:",g.error.format());return}let v=g.data,E=typeof h.recipientRawUserId=="number"?h.recipientRawUserId:void 0;if((v.type==="status-update"||E!==void 0)&&E!==I.internalUserId||!Xr(v,h,I.visibleSet,I.commentableSet)){Re(b,M);return}let C=en(v,h,I.commentableSet),x;if("recipientRawUserId"in h){let{recipientRawUserId:X,...$}=h;x=JSON.stringify($)}else C?x=JSON.stringify(h):x=k.data;b.writeEvent({event:null,id:M,data:x})}catch(h){U.error(`[SSE:${I.internalUserId}] processEntry error:`,h)}},ye=async(b,M)=>{let{request:k,internalUserId:I,cursor:h}=M,g=M.initialScope.visible,v=M.initialScope.commentable,E=0,O=setInterval(()=>{let T=++E;de(k,"refresh").then(K=>{T===E&&(g=K.visible,v=K.commentable)})},jt);b.onClose(()=>clearInterval(O));let C=h===null?qt:h,x=h!==null&&d!==void 0,X=[],$=null,N=T=>{Ie(T.id,C)||(C=T.id,Xe(b,T.id,T.message,{internalUserId:I,visibleSet:g,commentableSet:v}))},j=async(T,K)=>{let[se]=await T.xRange(D,"-","+",{COUNT:1});return se!==void 0&&!Ie(se.id,K)},H=async(T,K)=>{if(await j(T,K))return!1;let se=K;for(;;){let Z=await T.xRange(D,se,"+",{COUNT:Rt}),De=Z[0];if(De!==void 0&&De.id!==se&&await j(T,se))return!1;for(let ie of Z){if($!==null&&Ie($,ie.id))return!0;N(ie)}let pe=Z.at(-1);if(Z.length<Rt||pe===void 0||b.isClosed())return!0;se=pe.id}},q=c.subscribe(T=>{if(!x){N(T);return}Ie(T.id,C)||($===null&&($=T.id),X.push(T))},T=>{U.error(`[SSE:${I}] Fan-Out reader error:`,T),b.close()});if(b.onClose(q),h===null)try{let T=await d?.getClient();if(T){let K=await T.xRevRange(D,"+","-",{COUNT:1});K.length>0&&!Ie(K[0].id,C)&&(C=K[0].id)}}catch{}if(b.writeEvent({event:null,id:C===qt?null:C,data:Yt}),(0,ge.startSseHeartbeat)(b,{intervalMs:kt,retry:Pr,runtime:zt.systemSseRuntime}),h===null||d===void 0)return;let A=await d.getClient();if(A===void 0)throw new Error("redis client unavailable for the SSE catch-up");if(!await H(A,h)){b.writeRetry(Ht),b.writeEvent({event:"resync-required",id:null,data:""}),b.close();return}x=!1;for(let T of X.splice(0))N(T)};return{index:{loader:Me},api:{loader:W,action:Ye},sse:{loader:async({request:b,params:M})=>{let k,I=()=>{let g=new Headers;return k!==void 0&&g.append("Set-Cookie",k),g},h=g=>(0,ge.terminalStreamResponse)(g,{data:"",retryMs:Ht,headers:I()});try{let g=await e(b,{failureRedirect:null});k=g.cookie;let{user:v}=g;if(!v)return h("auth-required");let E=await r.getUserIdByExternalId(v.id);if(!E)return h("forbidden");if(M.endpoint!=="updates")return new Response("Not Found",{status:404,headers:I()});let O=(0,ge.readLastEventId)(b,Nt);if(O!==null&&!Pt(O))return U.warn(`[SSE:${E}] malformed resume cursor; asking the client to resync`),h("resync-required");let C=await de(b);return(0,ge.createSseResponse)({requestSignal:b.signal,headers:I(),onError:(x,X)=>U.error(`[SSE:${E}] ${X} failed:`,x),produce:x=>ye(x,{request:b,internalUserId:E,cursor:O,initialScope:C})})}catch(g){if(g instanceof Response)throw g;let v=g instanceof Error?g:new Error(String(g));return U.error(`500 sse name=${v.name} message=${v.message}`),new Response("Internal Server Error",{status:500,headers:I()})}}},attachment:{loader:async({request:b,params:M})=>{let k=null,I=(h,g,v)=>{let E=new Headers({"Content-Type":"application/json"});return v!==void 0&&E.set("Retry-After",String(v)),k&&E.append("Set-Cookie",k),new Response(JSON.stringify({error:{message:g}}),{status:h,headers:E})};try{let{user:h,cookie:g}=await e(b,{failureRedirect:null});if(k=g??null,!h)return I(401,"Unauthorized");if(b.method!=="GET"&&b.method!=="HEAD")return I(405,"Method not allowed");let v=t.attachmentIdCodec,E=t.readAttachment;if(!(v&&E))return I(404,"Attachment not found");let O=M.token??"",C=v.decode(O);if(C===null||!Number.isSafeInteger(C)||C<=0)return I(400,"Invalid attachment token");let x=await r.getUserIdByExternalId(h.id);if(!x)return I(403,"Forbidden");if(!z(x,Date.now()))return f.error(`429 attachment=${C} viewer=${x} reason=rate_limit`),I(429,"Too many requests",qr);let X=await de(b),$=await r.getAttachmentForUser(X,C,x);if(!$)return f.error(`404 attachment=${C} viewer=${x} reason=not_visible`),I(404,"Attachment not found");if($.fileSize!=null&&$.fileSize>V)return f.error(`413 attachment=${C} viewer=${x} reason=db_size`),I(413,"Attachment too large");if(!Y.tryAcquire())return f.error(`503 attachment=${C} viewer=${x} reason=concurrency`),I(503,"Too many concurrent downloads",Fr);let N=!1,j=()=>{N||(N=!0,Y.release())},H=!1;try{let q=b.method==="HEAD",A=await E($.filePath,{maxBytes:V,head:q,principal:s(x)});if(!A.ok){let he=jr(A.reason);return A.reason==="not_found"&&r.markAttachmentMissing(C).catch(Fe=>{f.error(`markAttachmentMissing failed attachment=${C} message=${Fe instanceof Error?Fe.message:"unknown"}`)}),f.error(`${he} attachment=${C} viewer=${x} reason=${A.reason} code=${A.code??"-"}`),I(he,Jr[he]??"Attachment storage unavailable")}let T=St($.fileType)??St(A.contentType)??"application/octet-stream",K=Vr.has(T),se=new URL(b.url).searchParams.get("download")==="1",Z=K?T:"application/octet-stream",De=K&&!se?"inline":"attachment",pe=A.size??A.bytes.byteLength,ie=new Headers({"Content-Type":Z,"Content-Length":String(pe),"Content-Disposition":`${De}; filename="${Gt($.fileName)}"; filename*=UTF-8''${Jt($.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return k&&ie.append("Set-Cookie",k),r.markAttachmentPresent(C).catch(he=>{f.error(`markAttachmentPresent failed attachment=${C} message=${he instanceof Error?he.message:"unknown"}`)}),f.info(`200 attachment=${C} viewer=${x} type=${Z} disposition=${De} bytes=${pe}`),q?new Response(null,{status:200,headers:ie}):(H=!0,new Response(Wr(A.bytes,j,Hr),{status:200,headers:ie}))}finally{H||j()}}catch(h){if(h instanceof Response)throw h;return f.error(`500 attachment=? viewer=? reason=unexpected message=${h instanceof Error?h.message:"unknown"}`),I(500,"Attachment request failed")}}}}}var Qt=require("@aiquants/mssql"),o=require("drizzle-orm");var Ae=t=>(0,o.getColumns)(t),ee=(t,e)=>{if(!t)return null;let r=t instanceof Date?t:new Date(t);if(Number.isNaN(r.getTime()))return typeof t=="string"?t:null;let s=r.getFullYear(),d=s<0?`-${String(-s).padStart(4,"0")}`:String(s).padStart(4,"0"),c=String(r.getMonth()+1).padStart(2,"0"),D=String(r.getDate()).padStart(2,"0");if(e==="YYYY-MM-DD")return`${d}-${c}-${D}`;let y=String(r.getHours()).padStart(2,"0"),L=String(r.getMinutes()).padStart(2,"0"),u=String(r.getSeconds()).padStart(2,"0");return`${d}-${c}-${D} ${y}:${L}:${u}`};function wt(t){let{db:e,tables:r,userTable:s,resolveUserId:d,encodeUserId:c,redis:D,cache:y,epochs:L}=t,{hub:u,internal:U,comment:f,label:V,hubLabel:z,userStatus:Y}=r,de=t.externalSources??[],Me=t.draftLabelNames&&t.draftLabelNames.length>0?t.draftLabelNames:[t.draftLabelName??"\u4E0B\u66F8\u304D"],ke=Me[0]??"\u4E0B\u66F8\u304D",W=t.logger??oe(1,"[DailyReportService]"),Ye=n=>(0,Qt.runWithTransactionRetry)(a=>e.transaction(i=>a(()=>n(i))),t.transactionRetry),Re="daily-report:ids",Xe=t.idsTtlMs??18e4,ye="daily-report:ids:epoch",Se="daily-report:business-date:",qe=t.businessDateTtlMs??3e5,b="daily-report:date-epoch:",M="daily-report:detail-epoch:",I=`${t.streamKey??"daily-report:sse-stream"}:v2`,h=t.streamMaxLen??1e4,g=n=>L.incrementEpoch(n),v=n=>gt(u.sourceType,n),E=(n,a)=>`${Re}:user:${n}:st:${a}`,O=n=>`${Re}:user:${n}:`,C=(n,a,i)=>`daily-report:date:${n}:user:${a}:st:${i}`,x=(n,a)=>`daily-report:date:${n}:user:${a}:`,X=(n,a,i)=>`daily-report:detail:${n}:user:${a}:st:${i}`,$=(n,a)=>`daily-report:detail:${n}:user:${a}:`,N=async(n,a)=>{let i=await D?.getClient();if(!i){W.warn(`[SSE] Redis client unavailable (${a})`);return}let p=Date.now();try{await i.xAdd(I,"*",{data:JSON.stringify(n)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:h}});let R=Date.now()-p;R>1e3&&W.warn(`[SSE] Slow publish (${a}): ${R}ms`)}catch(R){W.error(`[SSE] Redis publish failed (${a}):`,R)}},j=async()=>{try{let n=await D?.getClient();if(n===void 0)return null;let[a]=await n.xRevRange(I,"+","-",{COUNT:1});return a===void 0?null:a.id}catch(n){return W.error("[DailyReportService] SSE stream anchor read failed",n),null}},H=n=>n==null||n===""?null:/^\d+$/.test(n)?c(Number(n)):n,q=()=>{let n={};for(let a of de)n[`ext_${a.sourceType}`]=Ae(a.table);return n},A=n=>{let a=n;for(let i of de)a=a.leftJoin(i.table,(0,o.and)((0,o.eq)(u.sourceType,i.sourceType),(0,o.eq)(u.sourceIdNum,i.idColumn)));return a},T=(n,a,i)=>{let{hub:p,internal:R}=a,S=p.summary,w=[],_=null,P=null,J=null,F=null,Q=null,te=null,_e=[],fe=de.find(B=>B.sourceType===p.sourceType),Ce=fe?a[`ext_${fe.sourceType}`]:void 0;if(fe&&Ce){let B=fe.mapRow(Ce);B.content!==void 0&&(S=B.content),B.employeeName!==void 0&&(te=B.employeeName),B.category!==void 0&&(_=B.category),B.creationCategory!==void 0&&(P=B.creationCategory),B.visitTimeFrom!==void 0&&(J=B.visitTimeFrom),B.visitTimeTo!==void 0&&(F=B.visitTimeTo),B.customerName!==void 0&&(Q=B.customerName),B.interviewers!==void 0&&(w=B.interviewers),B.externalComments!==void 0&&(_e=B.externalComments)}else p.sourceType==="Internal"&&R&&(S=R.body);let me=(a.labels??[]).map(B=>({id:B.id,name:B.name,color:B.color})),re=a.postedCommentRows??[],G=ce(n.commentable,p.sourceType),ne=P?Me.includes(P):!1,rt=Te?.[0]??null;return ne&&rt&&!me.some(B=>B.id===rt)&&me.push({id:rt,name:ke,color:null}),{reportHubId:p.id,date:ee(p.businessDate,"YYYY-MM-DD"),author:a.creatorName??H(p.createdBy)??"",userId:p.userId?c(p.userId):"",sourceType:p.sourceType??"Internal",createdAt:ee(p.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:ee(p.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:H(p.updatedBy),employeeName:te??a.creatorName??H(p.createdBy),category:_,creationCategory:P,visitTimeFrom:J,visitTimeTo:F,customerName:Q,interviewers:w,subject:p.title,content:S,externalComments:G?_e:[],isRead:a.isRead??!1,isStarred:a.isStarred??!1,labels:me,postedComments:re.filter(B=>G||i!==void 0&&B.userId===i).map(B=>({...B,userId:c(B.userId),isMine:i?B.userId===i:!1})),attachments:a.attachments}},K=async(n,a)=>{let i=(0,o.aliasedTable)(z,"draft_label"),p=await we();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).from(u).leftJoin(i,(0,o.and)((0,o.eq)(i.hubId,u.id),(0,o.inArray)(i.labelId,p))).where((0,o.and)((0,o.isNull)(u.deletedAt),(0,o.or)((0,o.eq)(u.userId,a),(0,o.isNull)(u.userId),(0,o.isNull)(i.hubId)),v(n.visible))).orderBy((0,o.desc)(u.businessDate),(0,o.desc)(u.id))).map(S=>({...S,businessDate:ee(S.businessDate,"YYYY-MM-DD")}))},se=async(n,a,i)=>{let p=await ie(a);if(!p)return[];if(be(n.visible))return[];let R=(0,o.aliasedTable)(z,"draft_label"),S=await we();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).top(i).from(u).leftJoin(R,(0,o.and)((0,o.eq)(R.hubId,u.id),(0,o.inArray)(R.labelId,S))).where((0,o.and)((0,o.isNull)(u.deletedAt),(0,o.or)((0,o.eq)(u.userId,p),(0,o.isNull)(u.userId),(0,o.isNull)(R.hubId)),v(n.visible))).orderBy((0,o.desc)(u.businessDate),(0,o.desc)(u.id))).map(_=>({..._,businessDate:ee(_.businessDate,"YYYY-MM-DD")}))},Z=async(n,a)=>{let i=await A(e.select({hub:Ae(u),internal:Ae(U),creatorName:s.displayName,...q()}).from(u)).leftJoin(U,(0,o.eq)(u.id,U.hubId)).leftJoin(s,(0,o.eq)(u.userId,s.id)).where((0,o.and)((0,o.eq)(u.businessDate,o.sql`${a}`),(0,o.isNull)(u.deletedAt),v(n.visible))).orderBy((0,o.desc)(u.id)),p=await ze(i.map(R=>R.hub.id));return i.map(R=>T(n,{...R,attachments:p.get(R.hub.id)??[]}))},De=n=>`${Se}${n}`,pe=new Map,ie=async n=>{if(!t.disableUserIdCache&&pe.has(n))return pe.get(n)??null;let a=await d(n);return a!==null&&!t.disableUserIdCache&&pe.set(n,a),a},he=async(n,a,{forceRefresh:i=!1,snapshot:p=!1,ttlMsOverride:R,onFetchStart:S}={})=>{let w=await ie(a);if(!w)return{items:[],streamAnchor:null};if(be(n.visible))return{items:[],streamAnchor:await j()};let _=E(w,xe(n)),[P]=await y.getOrFetch({cacheKey:_,fetcher:async()=>{let J=await j(),F=await K(n,w);return xt(F)?[{items:F,streamAnchor:J}]:(W.warn("[DailyReportService] ids array is not in stream order; re-sorting (check SQL ORDER BY vs compareIdsStreamOrder, or concurrent row movement during the scan)"),[{items:[...F].sort(je),streamAnchor:J}])},onFetchStart:S,forceRefresh:i,snapshot:p,ttlMsOverride:R??Xe,epochKey:ye,refreshAheadRatio:.5});if(P===void 0)throw new Error("[DailyReportService] ids cache returned no record");return P},Fe=(n,a,{forceRefresh:i=!1,snapshot:p=!1,ttlMsOverride:R}={})=>{let S=ae(a);return S?be(n.visible)?Promise.resolve([]):y.getOrFetch({cacheKey:`${De(S)}:st:${xe(n)}`,fetcher:()=>Z(n,S),forceRefresh:i,snapshot:p,ttlMsOverride:R??qe}):Promise.resolve([])},Te=null,Ve=async()=>(Te!==null||(Te=(await e.select({id:V.id}).from(V).where((0,o.inArray)(V.name,Me)).orderBy(V.id)).map(a=>a.id)),Te),we=async()=>{let n=await Ve();return n.length>0?n:[-1]},Ze=async()=>{let n=await Ve();if(n.length===0)return null;let[a]=await e.select({id:V.id}).top(1).from(V).where((0,o.eq)(V.name,ke));return a?.id??n[0]},Xt=(n,a)=>a!=null?"absent":n!=null?"present":"unknown",ze=async n=>{let a=new Map,i=r.attachment,p=t.attachmentIdCodec;if(n.length===0||!i||!p)return a;let R=await e.select({id:i.id,hubId:i.hubId,fileName:i.fileName,fileType:i.fileType,fileSize:i.fileSize,createdAt:i.createdAt,objectCheckedAt:i.objectCheckedAt,objectMissingAt:i.objectMissingAt}).from(i).where((0,o.inArray)(i.hubId,n)).orderBy((0,o.asc)(i.createdAt),(0,o.asc)(i.id));for(let S of R){let w={id:p.encode(Number(S.id)),fileName:String(S.fileName),fileType:S.fileType?String(S.fileType):null,fileSize:S.fileSize!=null?Number(S.fileSize):null,createdAt:ee(S.createdAt,"YYYY-MM-DD HH:mm:ss"),state:Xt(S.objectCheckedAt,S.objectMissingAt)},_=a.get(Number(S.hubId));_?_.push(w):a.set(Number(S.hubId),[w])}return a},Zt=async(n,a,i)=>{let p=r.attachment;if(!p||be(n.visible))return null;let R=await we(),S=(0,o.aliasedTable)(z,"draft_label");return(await e.select({fileName:p.fileName,filePath:p.filePath,fileType:p.fileType,fileSize:p.fileSize}).top(1).from(p).innerJoin(u,(0,o.eq)(u.id,p.hubId)).leftJoin(S,(0,o.and)((0,o.eq)(S.hubId,u.id),(0,o.inArray)(S.labelId,R))).where((0,o.and)((0,o.eq)(p.id,a),(0,o.isNull)(u.deletedAt),(0,o.or)((0,o.eq)(u.userId,i),(0,o.isNull)(S.hubId)),v(n.visible))))[0]??null},er=async n=>{let a=r.attachment;if(!a)return;let i=new Date;try{await e.update(a).set({objectCheckedAt:i,objectMissingAt:i,updatedAt:i}).where((0,o.eq)(a.id,n))}catch(p){W.error("markAttachmentMissing failed",p)}},tr=async n=>{let a=r.attachment;if(!a)return;let i=new Date;try{await e.update(a).set({objectCheckedAt:i,objectMissingAt:null,updatedAt:i}).where((0,o.eq)(a.id,n))}catch(p){W.error("markAttachmentPresent failed",p)}},rr=async(n,a,i,{forceRefresh:p=!1,snapshot:R=!1,ttlMsOverride:S}={})=>{let w=await ie(i);if(!w)return[];let _=ae(a);if(!_)return[];if(be(n.visible))return[];let P=C(_,w,xe(n));return y.getOrFetch({cacheKey:P,fetcher:async()=>{let J=await we(),F=(0,o.aliasedTable)(z,"draft_label"),Q=await A(e.select({hub:Ae(u),internal:Ae(U),isRead:Y.isRead,isStarred:Y.isStarred,creatorName:s.displayName,...q()}).from(u)).leftJoin(U,(0,o.eq)(u.id,U.hubId)).leftJoin(Y,(0,o.and)((0,o.eq)(u.id,Y.hubId),(0,o.eq)(Y.userId,w))).leftJoin(F,(0,o.and)((0,o.eq)(F.hubId,u.id),(0,o.inArray)(F.labelId,J))).leftJoin(s,(0,o.eq)(u.userId,s.id)).where((0,o.and)((0,o.eq)(u.businessDate,o.sql`${_}`),(0,o.isNull)(u.deletedAt),(0,o.or)((0,o.eq)(u.userId,w),(0,o.isNull)(F.hubId)),v(n.visible))).orderBy((0,o.desc)(u.id));if(Q.length===0)return[];let te=Q.map(G=>G.hub.id),_e=await e.select({hubId:z.hubId,id:V.id,name:V.name,color:V.color}).from(z).innerJoin(V,(0,o.eq)(z.labelId,V.id)).where((0,o.inArray)(z.hubId,te)),fe=await e.select({hubId:f.hubId,id:f.id,body:f.body,createdAt:f.createdAt,userId:f.userId,userName:s.displayName}).from(f).leftJoin(s,(0,o.eq)(f.userId,s.id)).where((0,o.inArray)(f.hubId,te)).orderBy((0,o.asc)(f.createdAt)),Ce=await ze(te),me=new Map,re=new Map;for(let G of _e){let ne=me.get(G.hubId);ne||(ne=[],me.set(G.hubId,ne)),ne.push({id:G.id,name:G.name,color:G.color})}for(let G of fe){let ne=re.get(G.hubId);ne||(ne=[],re.set(G.hubId,ne)),ne.push({id:G.id,content:G.body,createdAt:ee(G.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:G.userId,userName:G.userName||""})}return Q.map(G=>{let ne=G.hub.id;return T(n,{...G,attachments:Ce.get(ne)??[],labels:me.get(ne)||[],postedCommentRows:re.get(ne)||[]},w)})},forceRefresh:p,snapshot:R,ttlMsOverride:S??qe,epochKey:`${b}${_}`})},Ne=async(n,a,i,{forceRefresh:p=!1,snapshot:R=!1,ttlMsOverride:S}={})=>{if(be(n.visible))return null;let w=X(a,i,xe(n));return(await y.getOrFetch({cacheKey:w,fetcher:async()=>{let P=await we(),J=(0,o.aliasedTable)(z,"draft_label"),F=await A(e.select({hub:Ae(u),internal:Ae(U),isRead:Y.isRead,isStarred:Y.isStarred,creatorName:s.displayName,...q()}).from(u)).leftJoin(U,(0,o.eq)(u.id,U.hubId)).leftJoin(Y,(0,o.and)((0,o.eq)(u.id,Y.hubId),(0,o.eq)(Y.userId,i))).leftJoin(J,(0,o.and)((0,o.eq)(J.hubId,u.id),(0,o.inArray)(J.labelId,P))).leftJoin(s,(0,o.eq)(u.userId,s.id)).where((0,o.and)((0,o.eq)(u.id,a),(0,o.isNull)(u.deletedAt),(0,o.or)((0,o.eq)(u.userId,i),(0,o.isNull)(J.hubId)),v(n.visible)));if(F.length===0)return[];let Q=F[0].hub.id,te=await e.select({id:V.id,name:V.name,color:V.color}).from(z).innerJoin(V,(0,o.eq)(z.labelId,V.id)).where((0,o.eq)(z.hubId,Q)),_e=await e.select({id:f.id,body:f.body,createdAt:f.createdAt,userId:f.userId,userName:s.displayName}).from(f).leftJoin(s,(0,o.eq)(f.userId,s.id)).where((0,o.eq)(f.hubId,Q)).orderBy((0,o.asc)(f.createdAt)),fe=await ze([Q]),Ce=te.map(re=>({id:re.id,name:re.name,color:re.color})),me=_e.map(re=>({id:re.id,content:re.body,createdAt:ee(re.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:re.userId,userName:re.userName||""}));return[T(n,{...F[0],attachments:fe.get(Q)??[],labels:Ce,postedCommentRows:me},i)]},forceRefresh:p,snapshot:R,ttlMsOverride:S??qe,epochKey:`${M}${a}`}))[0]??null},nr=async(n,a,i,p={})=>{let R=await ie(i);return R?Ne(n,a,R,p):null},ar=async(n,a)=>{let i=await we(),p=(0,o.aliasedTable)(z,"draft_label"),[R]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt}).top(1).from(u).leftJoin(p,(0,o.and)((0,o.eq)(p.hubId,u.id),(0,o.inArray)(p.labelId,i))).where((0,o.and)((0,o.eq)(u.id,n),(0,o.or)((0,o.eq)(u.userId,a),(0,o.isNull)(p.hubId))));return R??null},et=async(n,a,i)=>{let p=await ar(a,i);if(!p||p.deletedAt||!ce(n.visible,p.sourceType))throw new Error("Not Found")},sr=async(n,a,i,p,R,S)=>{await et(n,i,a);let w=await e.select().top(1).from(Y).where((0,o.and)((0,o.eq)(Y.hubId,i),(0,o.eq)(Y.userId,a))),_;if(w.length>0?w[0].isStarred!==R?_=(await e.update(Y).set({isStarred:R,updatedAt:new Date,updatedBy:String(a)}).output().where((0,o.and)((0,o.eq)(Y.hubId,i),(0,o.eq)(Y.userId,a))))[0]:_=w[0]:_=(await e.insert(Y).output().values({hubId:i,userId:a,isStarred:R,isRead:!1,createdAt:new Date,createdBy:String(a),updatedAt:new Date,updatedBy:String(a)}))[0],p){let P=ae(p);P&&(y.invalidatePrefix(x(P,a)),await g(`${b}${P}`))}return y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix($(i,a)),await g(`${M}${i}`),await N(Je.parse({type:"status-update",reportHubId:i,recipientRawUserId:a,statusType:"star",value:R,clientTempId:S}),"setStarStatus"),_},or=async(n,a,i,p,R,S)=>{await et(n,i,a);let w=await e.select().top(1).from(Y).where((0,o.and)((0,o.eq)(Y.hubId,i),(0,o.eq)(Y.userId,a))),_;if(w.length>0?w[0].isRead!==R?_=(await e.update(Y).set({isRead:R,updatedAt:new Date,updatedBy:String(a)}).output().where((0,o.and)((0,o.eq)(Y.hubId,i),(0,o.eq)(Y.userId,a))))[0]:_=w[0]:_=(await e.insert(Y).output().values({hubId:i,userId:a,isRead:R,isStarred:!1,createdAt:new Date,createdBy:String(a),updatedAt:new Date,updatedBy:String(a)}))[0],p){let P=ae(p);P&&(y.invalidatePrefix(x(P,a)),await g(`${b}${P}`))}return y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix($(i,a)),await g(`${M}${i}`),await N(Je.parse({type:"status-update",reportHubId:i,recipientRawUserId:a,statusType:"read",value:R,clientTempId:S}),"setReadStatus"),_},It=async(n,a)=>{if(a===null)return;let i=await we(),[p]=await e.select({hubId:z.hubId}).top(1).from(z).where((0,o.and)((0,o.eq)(z.hubId,n),(0,o.inArray)(z.labelId,i)));return p?a:void 0},ir=async(n,a,i,p,R,S)=>{let[w]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt,userId:u.userId}).top(1).from(u).where((0,o.eq)(u.id,i));if(!w||w.deletedAt)throw new Error("Not Found");if(await et(n,i,a),!ce(n.commentable,w.sourceType))throw new Error("Comments are restricted by the viewer's comment permission");if(w.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let _=await It(i,w.userId),[P]=await e.insert(f).output().values({hubId:i,userId:a,body:p,createdAt:new Date,createdBy:String(a),updatedAt:new Date,updatedBy:String(a)}),[J]=await e.select({displayName:s.displayName}).top(1).from(s).where((0,o.eq)(s.id,a)),F=J?.displayName??"";if(R){let te=ae(R);te&&(y.invalidatePrefix(`daily-report:date:${te}:user:`),await g(`${b}${te}`))}y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(`daily-report:detail:${i}:user:`),await g(`${M}${i}`);let Q={id:P.id,userId:c(P.userId),userName:F,content:P.body,createdAt:ee(P.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await N(dt.parse({type:"comment-add",reportHubId:i,comment:Q,clientTempId:S,recipientRawUserId:_,sourceType:w.sourceType}),"addComment"),Q},lr=async(n,a)=>await n.select().top(1).from(f).where((0,o.eq)(f.id,a)),ur=async(n,a,i,p,R,S)=>{let w=await lr(e,p);if(w.length===0)throw new Error("Not Found");if(w[0].hubId!==i)throw new Error("Not Found");let[_]=await e.select({userId:u.userId,sourceType:u.sourceType}).top(1).from(u).where((0,o.eq)(u.id,w[0].hubId));if(!(_&&ce(n.visible,_.sourceType)))throw new Error("Not Found");if(w[0].userId!==a)throw new Error("Unauthorized");let P=await It(i,_.userId);if(await e.delete(f).where((0,o.eq)(f.id,p)),R){let J=ae(R);J&&(y.invalidatePrefix(`daily-report:date:${J}:user:`),await g(`${b}${J}`))}y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(`daily-report:detail:${i}:user:`),await g(`${M}${i}`),await N(ct.parse({type:"comment-delete",reportHubId:i,commentId:p,clientTempId:S,recipientRawUserId:P,sourceType:_?.sourceType}),"deleteComment")},dr=async(n,a,i)=>{W.info("createDailyReport called",{userId:n,businessDate:a});let[p]=await e.select({displayName:s.displayName}).from(s).where((0,o.eq)(s.id,n)),R=p?.displayName??c(n);try{let S=await Ye(async P=>{W.info("Starting transaction");let J=`internal-temp-${Date.now()}-${Math.random()}`,[F]=await P.insert(u).output().values({sourceType:"Internal",sourceId:J,businessDate:new Date(a),userId:n,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)});await P.update(u).set({sourceId:String(F.id)}).where((0,o.eq)(u.id,F.id)),W.info("Hub created",F),await P.insert(U).values({hubId:F.id,body:"",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)}),W.info("Internal created"),W.info("Calling getDraftLabelId");let Q=await Ze();W.info("draftLabelId",Q);let te=[];return Q&&(await P.insert(z).values({hubId:F.id,labelId:Q,createdAt:new Date,createdBy:String(n)}),te.push({id:Q,name:ke,color:null})),W.info("Label assigned"),{reportHubId:F.id,date:a,createdAt:ee(F.createdAt,"YYYY-MM-DD HH:mm:ss"),author:R,userId:c(n),sourceType:"Internal",employeeName:R,updatedBy:c(n),updatedAt:ee(F.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:F.title,content:"",externalComments:[],isRead:!0,isStarred:!1,labels:te,postedComments:[],attachments:[]}}),w=ae(a);w&&y.invalidatePrefix(x(w,n)),y.invalidatePrefix(Se),y.invalidatePrefix(O(n)),await g(ye),w&&await g(`${b}${w}`);let _=await Ne(ue.unrestricted("post-write self read: the writer always sees the row they just wrote"),S.reportHubId,n,{forceRefresh:!0});if(_){let P=await Ve(),J=_.labels.some(F=>P.includes(F.id));await N(pt.parse({type:"report-create",reportHubId:_.reportHubId,report:_,clientTempId:i,recipientRawUserId:J?n:void 0}),"createDailyReport")}return _??S}catch(S){throw W.error("Error in createDailyReport",S),S}},Ke=async(n,a)=>await n.select().top(1).from(u).where((0,o.eq)(u.id,a)),tt=async(n,a,i)=>{await n.update(u).set(i).where((0,o.eq)(u.id,a))},At=async(n,a,i)=>{await n.update(U).set(i).where((0,o.eq)(U.hubId,a))},Tt=async(n,a,i)=>{await n.delete(z).where((0,o.and)((0,o.eq)(z.hubId,a),(0,o.eq)(z.labelId,i)))};return{streamKey:I,streamMaxLen:h,clearCache:async()=>{y.clearAll(),pe.clear(),Te=null,L&&await g(ye),W.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(n,a)=>{y.invalidatePrefix(Se),y.invalidatePrefix(Re),await g(ye);for(let i of new Set(n))y.invalidatePrefix(`daily-report:detail:${i}:user:`),await g(`${M}${i}`);for(let i of new Set(a)){let p=ae(i);p&&await g(`${b}${p}`)}},getUserIdByExternalId:ie,getDailyReportIdsByExternalId:he,getDailyReportIdsFirstPageByExternalId:se,readSseStreamAnchor:j,getDailyReportsByBusinessDate:Fe,getDailyReportsByBusinessDateByExternalId:rr,getDailyReportDetailById:Ne,getDailyReportDetailByIdByExternalId:nr,getDraftLabelId:Ze,getAttachmentsByHubIds:ze,getAttachmentForUser:Zt,markAttachmentMissing:er,markAttachmentPresent:tr,setStarStatus:sr,setReadStatus:or,addComment:ir,deleteComment:ur,createDailyReport:dr,updateDailyReport:async(n,a,i,p)=>{let R=await Ke(e,n);if(!R.length||R[0].deletedAt)throw new Error("Not Found");if(R[0].userId!==a)throw new Error("Unauthorized");await Ye(async _=>{i.title!==void 0&&await tt(_,n,{title:i.title,updatedAt:new Date,updatedBy:String(a)}),i.content!==void 0&&await At(_,n,{body:i.content,updatedAt:new Date,updatedBy:String(a)})}),y.invalidate(`daily-report:detail:${n}`),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(Se),await g(`${M}${n}`);let S=ae(ee(R[0].businessDate,"YYYY-MM-DD"));S&&(y.invalidatePrefix(`daily-report:date:${S}:user:`),await g(`${b}${S}`));let w=await Ne(ue.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,a,{forceRefresh:!0});if(w){let _=await Ve(),P=w.labels.some(J=>_.includes(J.id));await N(mt.parse({type:"report-update",reportHubId:w.reportHubId,report:w,clientTempId:p,recipientRawUserId:P?a:void 0}),"updateDailyReport")}},publishDailyReport:async(n,a,i)=>{let p=await Ke(e,n);if(!p.length)throw new Error("Not Found");if(p[0].userId!==a)throw new Error("Unauthorized");let R=await Ze();if(!R)return null;if(await Tt(e,n,R),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(Se),y.invalidatePrefix(Re),await g(ye),p[0].businessDate){let _=ae(ee(p[0].businessDate,"YYYY-MM-DD"));_&&await g(`${b}${_}`)}let S=ae(ee(p[0].businessDate,"YYYY-MM-DD"));S&&y.invalidatePrefix(x(S,a));let w=await Ne(ue.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,a,{forceRefresh:!0});return w&&await N(yt.parse({type:"report-publish",reportHubId:w.reportHubId,report:w,clientTempId:i}),"publishDailyReport"),w??null},deleteDailyReport:async(n,a,i)=>{let p=await Ke(e,n);if(!p.length||p[0].deletedAt)throw new Error("Not Found");if(p[0].userId!==a)throw new Error("Unauthorized");if(await tt(e,n,{deletedAt:new Date,deletedBy:String(a),updatedAt:new Date,updatedBy:String(a)}),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(Se),y.invalidatePrefix(Re),await g(ye),p[0].businessDate){let R=ae(ee(p[0].businessDate,"YYYY-MM-DD"));R&&await g(`${b}${R}`)}await N(ht.parse({type:"report-delete",reportHubId:n,clientTempId:i,sourceType:p[0].sourceType}),"deleteDailyReport")},findDailyReportHubById:Ke,updateDailyReportHub:tt,updateDailyReportInternal:At,deleteDailyReportLabel:Tt}}var Oe=require("drizzle-orm");function Wt(t){let e=[],r=t&&t.length>0?t:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let s of r){let c=`daily_report_${s.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:c,name:s.name,description:s.description??`${s.name} daily report access`}),s.includeCommentResource!==!1&&e.push({resourceKey:`${c}_comment`,name:`${s.name} Comment`,description:`${s.name} daily report comment access`})}return e}async function tn(t,e,r){let s=t,d=e.TMResource,c=r.appKey,D=r.actor??"system:daily-report",y=new Date,L=r.resources??Wt(r.sources);for(let u of L){let U=await s.select().from(d).where((0,Oe.and)((0,Oe.eq)(d.appKey,c),(0,Oe.eq)(d.resourceKey,u.resourceKey)));(!U||U.length===0)&&await s.insert(d).values({appKey:c,resourceKey:u.resourceKey,name:u.name,description:u.description??null,createdAt:y,createdBy:D,updatedAt:y,updatedBy:D})}}var rn=oe(1,"[DailyReportExternalSource]"),nn=(t,e,r,s=rn)=>{if(!t)return[];try{let d=JSON.parse(t);return Array.isArray(d)?d.map(r).filter(c=>c!==null):(s.warn(`Unexpected ${e} format: not an array`),[])}catch(d){return s.warn(`Failed to parse ${e}:`,d),[]}};var He=require("drizzle-orm"),l=require("drizzle-orm/mssql-core");function an(t,e){let r=(0,l.mssqlSchema)(t),s=e.userTable,d=r.table("DailyReportHub",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,l.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,l.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,l.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(He.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,l.date)("business_date"),userId:(0,l.bigint)("user_id",{mode:"number"}),title:(0,l.nvarchar)("title",{length:200}),summary:(0,l.nvarchar)("summary",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,l.datetime2)("deleted_at"),deletedBy:(0,l.nvarchar)("deleted_by",{length:50})},f=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_pk`,columns:[f.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_user_id_fk`,columns:[f.userId],foreignColumns:[s.id]}),(0,l.index)(`${t}_DailyReportHub_business_date_index`).on(f.businessDate),(0,l.index)(`${t}_DailyReportHub_updated_at_index`).on(f.updatedAt),(0,l.index)(`${t}_DailyReportHub_source_index`).on(f.sourceType,f.sourceId),(0,l.index)(`${t}_DailyReportHub_user_id_index`).on(f.userId),(0,l.index)(`${t}_DailyReportHub_business_date_id_index`).on((0,He.desc)(f.businessDate),(0,He.desc)(f.id)),(0,l.index)(`${t}_DailyReportHub_deleted_at_index`).on(f.deletedAt)]),c=r.table("DailyReportInternal",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}),metadata:(0,l.nvarchar)("metadata",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},f=>[(0,l.primaryKey)({name:`${t}_DailyReportInternal_pk`,columns:[f.hubId]}),(0,l.foreignKey)({name:`${t}_DailyReportInternal_hub_id_fk`,columns:[f.hubId],foreignColumns:[d.id]})]),D=r.table("DailyReportComment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},f=>[(0,l.primaryKey)({name:`${t}_DailyReportComment_pk`,columns:[f.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_hub_id_fk`,columns:[f.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_user_id_fk`,columns:[f.userId],foreignColumns:[s.id]}),(0,l.index)(`${t}_DailyReportComment_hub_id_index`).on(f.hubId)]),y=r.table("DailyReportLabel",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}),name:(0,l.nvarchar)("name",{length:50}).notNull(),color:(0,l.nvarchar)("color",{length:20}),sortOrder:(0,l.int)("sort_order"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},f=>[(0,l.primaryKey)({name:`${t}_DailyReportLabel_pk`,columns:[f.id]}),(0,l.foreignKey)({name:`${t}_DailyReportLabel_user_id_fk`,columns:[f.userId],foreignColumns:[s.id]})]),L=r.table("DailyReportHub_Label",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,l.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull()},f=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_Label_pk`,columns:[f.hubId,f.labelId]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_hub_id_fk`,columns:[f.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_label_id_fk`,columns:[f.labelId],foreignColumns:[y.id]})]),u=r.table("DailyReportUserStatus",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,l.bit)("is_read").default(!1).notNull(),isStarred:(0,l.bit)("is_starred").default(!1).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},f=>[(0,l.primaryKey)({name:`${t}_DailyReportUserStatus_pk`,columns:[f.hubId,f.userId]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_hub_id_fk`,columns:[f.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_user_id_fk`,columns:[f.userId],foreignColumns:[s.id]})]),U=r.table("DailyReportAttachment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),uploadedBy:(0,l.bigint)("uploaded_by",{mode:"number"}),sourceKey:(0,l.nvarchar)("source_key",{length:200}).notNull(),fileName:(0,l.nvarchar)("file_name",{length:255}).notNull(),filePath:(0,l.nvarchar)("file_path",{length:"max"}).notNull(),fileType:(0,l.nvarchar)("file_type",{length:100}),fileSize:(0,l.bigint)("file_size",{mode:"number"}),objectCheckedAt:(0,l.datetime2)("object_checked_at"),objectMissingAt:(0,l.datetime2)("object_missing_at"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},f=>[(0,l.primaryKey)({name:`${t}_DailyReportAttachment_pk`,columns:[f.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_hub_id_fk`,columns:[f.hubId],foreignColumns:[d.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_uploaded_by_fk`,columns:[f.uploadedBy],foreignColumns:[s.id]}),(0,l.uniqueIndex)(`${t}_DailyReportAttachment_source_unique`).on(f.hubId,f.sourceKey),(0,l.index)(`${t}_DailyReportAttachment_hub_id_index`).on(f.hubId,f.createdAt)]);return{hub:d,internal:c,comment:D,attachment:U,label:y,hubLabel:L,userStatus:u}}function sn(t){t.redis||(t.logger??console).warn("[DailyReport] redis provider is not injected: cross-worker cache invalidation is disabled (staleness is bounded only by TTL) and SSE publishing is skipped.");let e=ot(t.redis),r=new Le({defaultTtlMs:t.cacheDefaultTtlMs??6e4},e),s=wt({...t,cache:r,epochs:e}),d=new $e({redis:t.redis,streamKey:s.streamKey,cache:r,logger:t.logger}),c=Dt({authenticate:t.authenticate,resolveVisibleSourceTypes:t.resolveVisibleSourceTypes,service:s,encodeUserId:t.encodeUserId,attachmentIdCodec:t.attachmentIdCodec,readAttachment:t.readAttachment,attachmentMaxBytes:t.attachmentMaxBytes,attachmentRateLimitPerMinute:t.attachmentRateLimitPerMinute,attachmentConcurrency:t.attachmentConcurrency,redis:t.redis,sseReader:d,streamKey:s.streamKey,loginRedirectPath:t.loginRedirectPath,enableDevCacheClear:t.enableDevCacheClear,logger:t.logger});return{service:s,cache:r,epochs:e,sseReader:d,streamKey:s.streamKey,knownSourceTypes:[...new Set(["Internal",...(t.externalSources??[]).map(D=>D.sourceType)])],...c}}0&&(module.exports={DAILY_REPORT_SSE_CATCH_UP_BATCH,DAILY_REPORT_SSE_VISIBILITY_REFRESH_MS,DailyReportSseReader,DailyReportViewerScope,SqlResultCache,asciiFallbackFileName,buildVisibleSourceTypeCondition,computeSourceTypeDigest,computeViewerScopeDigest,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,deniesEverySourceType,encodeRfc8187,formatDateValue,generateETag,isSourceTypeVisible,isStreamIdLte,jsonResponseWithETag,normalizeVisibleSourceTypes,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
|