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