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